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  }