github.com/anacrolix/torrent@v1.61.0/internal/indexed/misc.go (about) 1 package indexed 2 3 import ( 4 g "github.com/anacrolix/generics" 5 "github.com/anacrolix/generics/option" 6 "github.com/anacrolix/missinggo/v2/panicif" 7 ) 8 9 type triggerFunc[R any] func(old, new g.Option[R]) 10 11 type CompareFunc[T any] func(a, b T) int 12 13 type Pair[K, V any] struct { 14 Left K 15 Right V 16 } 17 18 func NewPair[K, V any](left K, right V) Pair[K, V] { 19 return Pair[K, V]{Left: left, Right: right} 20 } 21 22 func (me Pair[K, V]) Flip() Pair[V, K] { 23 return Pair[V, K]{Left: me.Right, Right: me.Left} 24 } 25 26 func pairMapRight[K, V any](me Pair[K, V]) V { 27 return me.Right 28 } 29 30 // A full index that doesn't require mapping records. 31 func NewFullIndex[R comparable](from tableInterface[R], cmpFunc CompareFunc[R], minRecord R) (index Index[R]) { 32 return NewFullMappedIndex( 33 from, 34 cmpFunc, 35 func(r R) R { return r }, 36 minRecord, 37 ) 38 } 39 40 // An index on a mapped form of the upstream data. What about cross-table and partial indexes? 41 func NewFullMappedIndex[F, T comparable]( 42 from tableInterface[F], 43 cmpFunc CompareFunc[T], 44 mapFunc func(F) T, 45 minRecord T, 46 ) Index[T] { 47 var index *table[T] 48 g.InitNew(&index) 49 index.Init(cmpFunc) 50 index.SetMinRecord(minRecord) 51 from.addIndex( 52 index, 53 func(old, new g.Option[F]) { 54 index.Change(option.Map(mapFunc, old), option.Map(mapFunc, new)) 55 panicif.NotEq(from.Len(), index.Len()) 56 }, 57 ) 58 return index 59 } 60 61 func (me *table[R]) addIndex(index genericRelation, trigger triggerFunc[R]) { 62 me.indexes = append(me.indexes, index) 63 me.indexTriggers = append(me.indexTriggers, trigger) 64 }