github.com/anacrolix/torrent@v1.61.0/internal/indexed/map_test.go (about) 1 package indexed 2 3 import ( 4 "cmp" 5 "slices" 6 "testing" 7 "time" 8 9 "github.com/anacrolix/missinggo/v2/panicif" 10 "github.com/anacrolix/torrent/internal/extracmp" 11 "github.com/go-quicktest/qt" 12 "golang.org/x/exp/constraints" 13 ) 14 15 type overdueRecord struct { 16 active bool 17 overdue bool 18 when time.Time 19 } 20 21 type overdueRecordPrimaryKey int 22 23 func (me overdueRecordPrimaryKey) Compare(other overdueRecordPrimaryKey) int { 24 return cmp.Compare(me, other) 25 } 26 27 func overdueRecordIndexCompare(l, r overdueRecord) int { 28 return cmp.Or( 29 extracmp.CompareBool(l.active, r.active), 30 -extracmp.CompareBool(l.overdue, r.overdue), 31 l.when.Compare(r.when)) 32 } 33 34 func TestOverdue(t *testing.T) { 35 var a Map[int, overdueRecord] 36 a.Init(func(a, b int) int { 37 return cmp.Compare(a, b) 38 }) 39 idx := NewFullMappedIndex( 40 &a, 41 func(a, b Pair[overdueRecord, int]) int { 42 return cmp.Or(overdueRecordIndexCompare(a.Left, b.Left), cmp.Compare(a.Right, b.Right)) 43 }, 44 Pair[int, overdueRecord].Flip, 45 func() (ret Pair[overdueRecord, int]) { 46 ret.Left.overdue = true 47 return 48 }(), 49 ) 50 qt.Assert(t, qt.CmpEquals(nil, slices.Collect(a.Iter))) 51 rows := []overdueRecord{ 52 {overdue: true}, 53 {overdue: true, when: time.Now().Add(-time.Minute)}, 54 {overdue: true, when: time.Now().Add(time.Minute)}, 55 {overdue: false, when: time.Now().Add(-time.Minute)}, 56 {overdue: false, when: time.Now().Add(time.Minute)}, 57 {overdue: true}, 58 {overdue: false}, 59 {overdue: false, active: true}, 60 } 61 for i, row := range rows { 62 panicif.False(a.Create(i, row)) 63 } 64 itered := slices.Collect(MapPairIterLeft(a.Iter)) 65 qt.Assert(t, qt.HasLen(itered, len(rows))) 66 iteredPks := slices.Collect(MapPairIterRight(idx.Iter)) 67 qt.Assert(t, qt.CmpEquals([]int{0, 5, 1, 2, 6, 3, 4, 7}, iteredPks)) 68 var overdue []int 69 gte := idx.MinRecord() 70 gte.Left.overdue = false 71 lt := gte 72 lt.Left.when = time.Now().Add(1) 73 for rowid := range MapPairIterRight(IterRange(idx, gte, lt)) { 74 overdue = append(overdue, rowid) 75 } 76 qt.Assert(t, qt.CmpEquals(overdue, []int{6, 3})) 77 for _, pk := range overdue { 78 a.Update(pk, func(r overdueRecord) overdueRecord { 79 r.overdue = true 80 return r 81 }) 82 } 83 qt.Assert(t, qt.CmpEquals([]int{0, 5, 6, 1, 3, 2, 4, 7}, slices.Collect(MapPairIterRight(idx.Iter)))) 84 } 85 86 type orderedPrimaryKey[T constraints.Ordered] struct { 87 inner T 88 } 89 90 func (me orderedPrimaryKey[T]) Compare(other orderedPrimaryKey[T]) int { 91 return cmp.Compare(me.inner, other.inner) 92 } 93 94 func TestEnsureAndUpdate(t *testing.T) { 95 var a Table[int] 96 a.Init(cmp.Compare[int]) 97 a.Create(1) 98 a.Update(1, func(r int) int { 99 // Check the record was created with the necessary key values for discovery. 100 panicif.NotEq(r, 1) 101 return r 102 }) 103 }