github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/pkg/rtree/rtree_test.go (about) 1 // Copyright 2020 PingCAP, Inc. Licensed under Apache-2.0. 2 3 package rtree_test 4 5 import ( 6 "fmt" 7 "testing" 8 9 . "github.com/pingcap/check" 10 11 "github.com/pingcap/br/pkg/rtree" 12 ) 13 14 func Test(t *testing.T) { 15 TestingT(t) 16 } 17 18 var _ = Suite(&testRangeTreeSuite{}) 19 20 type testRangeTreeSuite struct{} 21 22 func newRange(start, end []byte) *rtree.Range { 23 return &rtree.Range{ 24 StartKey: start, 25 EndKey: end, 26 } 27 } 28 29 func (s *testRangeTreeSuite) TestRangeTree(c *C) { 30 rangeTree := rtree.NewRangeTree() 31 c.Assert(rangeTree.Get(newRange([]byte(""), []byte(""))), IsNil) 32 33 search := func(key []byte) *rtree.Range { 34 rg := rangeTree.Get(newRange(key, []byte(""))) 35 if rg == nil { 36 return nil 37 } 38 return rg.(*rtree.Range) 39 } 40 assertIncomplete := func(startKey, endKey []byte, ranges []rtree.Range) { 41 incomplete := rangeTree.GetIncompleteRange(startKey, endKey) 42 c.Logf("%#v %#v\n%#v\n%#v\n", startKey, endKey, incomplete, ranges) 43 c.Assert(len(incomplete), Equals, len(ranges)) 44 for idx, rg := range incomplete { 45 c.Assert(rg.StartKey, DeepEquals, ranges[idx].StartKey) 46 c.Assert(rg.EndKey, DeepEquals, ranges[idx].EndKey) 47 } 48 } 49 assertAllComplete := func() { 50 for s := 0; s < 0xfe; s++ { 51 for e := s + 1; e < 0xff; e++ { 52 start := []byte{byte(s)} 53 end := []byte{byte(e)} 54 assertIncomplete(start, end, []rtree.Range{}) 55 } 56 } 57 } 58 59 range0 := newRange([]byte(""), []byte("a")) 60 rangeA := newRange([]byte("a"), []byte("b")) 61 rangeB := newRange([]byte("b"), []byte("c")) 62 rangeC := newRange([]byte("c"), []byte("d")) 63 rangeD := newRange([]byte("d"), []byte("")) 64 65 rangeTree.Update(*rangeA) 66 c.Assert(rangeTree.Len(), Equals, 1) 67 assertIncomplete([]byte("a"), []byte("b"), []rtree.Range{}) 68 assertIncomplete([]byte(""), []byte(""), 69 []rtree.Range{ 70 {StartKey: []byte(""), EndKey: []byte("a")}, 71 {StartKey: []byte("b"), EndKey: []byte("")}, 72 }) 73 74 rangeTree.Update(*rangeC) 75 c.Assert(rangeTree.Len(), Equals, 2) 76 assertIncomplete([]byte("a"), []byte("c"), []rtree.Range{ 77 {StartKey: []byte("b"), EndKey: []byte("c")}, 78 }) 79 assertIncomplete([]byte("b"), []byte("c"), []rtree.Range{ 80 {StartKey: []byte("b"), EndKey: []byte("c")}, 81 }) 82 assertIncomplete([]byte(""), []byte(""), 83 []rtree.Range{ 84 {StartKey: []byte(""), EndKey: []byte("a")}, 85 {StartKey: []byte("b"), EndKey: []byte("c")}, 86 {StartKey: []byte("d"), EndKey: []byte("")}, 87 }) 88 89 c.Assert(search([]byte{}), IsNil) 90 c.Assert(search([]byte("a")), DeepEquals, rangeA) 91 c.Assert(search([]byte("b")), IsNil) 92 c.Assert(search([]byte("c")), DeepEquals, rangeC) 93 c.Assert(search([]byte("d")), IsNil) 94 95 rangeTree.Update(*rangeB) 96 c.Assert(rangeTree.Len(), Equals, 3) 97 c.Assert(search([]byte("b")), DeepEquals, rangeB) 98 assertIncomplete([]byte(""), []byte(""), 99 []rtree.Range{ 100 {StartKey: []byte(""), EndKey: []byte("a")}, 101 {StartKey: []byte("d"), EndKey: []byte("")}, 102 }) 103 104 rangeTree.Update(*rangeD) 105 c.Assert(rangeTree.Len(), Equals, 4) 106 c.Assert(search([]byte("d")), DeepEquals, rangeD) 107 assertIncomplete([]byte(""), []byte(""), []rtree.Range{ 108 {StartKey: []byte(""), EndKey: []byte("a")}, 109 }) 110 111 // None incomplete for any range after insert range 0 112 rangeTree.Update(*range0) 113 c.Assert(rangeTree.Len(), Equals, 5) 114 115 // Overwrite range B and C. 116 rangeBD := newRange([]byte("b"), []byte("d")) 117 rangeTree.Update(*rangeBD) 118 c.Assert(rangeTree.Len(), Equals, 4) 119 assertAllComplete() 120 121 // Overwrite range BD, c-d should be empty 122 rangeTree.Update(*rangeB) 123 c.Assert(rangeTree.Len(), Equals, 4) 124 assertIncomplete([]byte(""), []byte(""), []rtree.Range{ 125 {StartKey: []byte("c"), EndKey: []byte("d")}, 126 }) 127 128 rangeTree.Update(*rangeC) 129 c.Assert(rangeTree.Len(), Equals, 5) 130 assertAllComplete() 131 } 132 133 func (s *testRangeTreeSuite) TestRangeIntersect(c *C) { 134 rg := newRange([]byte("a"), []byte("c")) 135 136 start, end, isIntersect := rg.Intersect([]byte(""), []byte("")) 137 c.Assert(isIntersect, Equals, true) 138 c.Assert(start, DeepEquals, []byte("a")) 139 c.Assert(end, DeepEquals, []byte("c")) 140 141 start, end, isIntersect = rg.Intersect([]byte(""), []byte("a")) 142 c.Assert(isIntersect, Equals, false) 143 c.Assert(start, DeepEquals, []byte(nil)) 144 c.Assert(end, DeepEquals, []byte(nil)) 145 146 start, end, isIntersect = rg.Intersect([]byte(""), []byte("b")) 147 c.Assert(isIntersect, Equals, true) 148 c.Assert(start, DeepEquals, []byte("a")) 149 c.Assert(end, DeepEquals, []byte("b")) 150 151 start, end, isIntersect = rg.Intersect([]byte("a"), []byte("b")) 152 c.Assert(isIntersect, Equals, true) 153 c.Assert(start, DeepEquals, []byte("a")) 154 c.Assert(end, DeepEquals, []byte("b")) 155 156 start, end, isIntersect = rg.Intersect([]byte("aa"), []byte("b")) 157 c.Assert(isIntersect, Equals, true) 158 c.Assert(start, DeepEquals, []byte("aa")) 159 c.Assert(end, DeepEquals, []byte("b")) 160 161 start, end, isIntersect = rg.Intersect([]byte("b"), []byte("c")) 162 c.Assert(isIntersect, Equals, true) 163 c.Assert(start, DeepEquals, []byte("b")) 164 c.Assert(end, DeepEquals, []byte("c")) 165 166 start, end, isIntersect = rg.Intersect([]byte(""), []byte{1}) 167 c.Assert(isIntersect, Equals, false) 168 c.Assert(start, DeepEquals, []byte(nil)) 169 c.Assert(end, DeepEquals, []byte(nil)) 170 171 start, end, isIntersect = rg.Intersect([]byte("c"), []byte("")) 172 c.Assert(isIntersect, Equals, false) 173 c.Assert(start, DeepEquals, []byte(nil)) 174 c.Assert(end, DeepEquals, []byte(nil)) 175 } 176 177 func BenchmarkRangeTreeUpdate(b *testing.B) { 178 rangeTree := rtree.NewRangeTree() 179 for i := 0; i < b.N; i++ { 180 item := rtree.Range{ 181 StartKey: []byte(fmt.Sprintf("%20d", i)), 182 EndKey: []byte(fmt.Sprintf("%20d", i+1)), 183 } 184 rangeTree.Update(item) 185 } 186 }