github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/kv/mem_buffer_test.go (about)

     1  // Copyright 2015 PingCAP, Inc.
     2  //
     3  // Copyright 2015 Wenbin Xiao
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package kv
    17  
    18  import (
    19  	"fmt"
    20  	"math/rand"
    21  	"testing"
    22  
    23  	. "github.com/insionng/yougam/libraries/pingcap/check"
    24  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/testleak"
    25  )
    26  
    27  const (
    28  	startIndex = 0
    29  	testCount  = 2
    30  	indexStep  = 2
    31  )
    32  
    33  func TestT(t *testing.T) {
    34  	TestingT(t)
    35  }
    36  
    37  var _ = Suite(&testKVSuite{})
    38  
    39  type testKVSuite struct {
    40  	bs []MemBuffer
    41  }
    42  
    43  func (s *testKVSuite) SetUpSuite(c *C) {
    44  	s.bs = make([]MemBuffer, 2)
    45  	s.bs[0] = NewRBTreeBuffer()
    46  	s.bs[1] = NewMemDbBuffer()
    47  }
    48  
    49  func (s *testKVSuite) TearDownSuite(c *C) {
    50  	for _, buffer := range s.bs {
    51  		buffer.Release()
    52  	}
    53  }
    54  
    55  func insertData(c *C, buffer MemBuffer) {
    56  	for i := startIndex; i < testCount; i++ {
    57  		val := encodeInt(i * indexStep)
    58  		err := buffer.Set(val, val)
    59  		c.Assert(err, IsNil)
    60  	}
    61  }
    62  
    63  func encodeInt(n int) []byte {
    64  	return []byte(fmt.Sprintf("%010d", n))
    65  }
    66  
    67  func decodeInt(s []byte) int {
    68  	var n int
    69  	fmt.Sscanf(string(s), "%010d", &n)
    70  	return n
    71  }
    72  
    73  func valToStr(c *C, iter Iterator) string {
    74  	val := iter.Value()
    75  	return string(val)
    76  }
    77  
    78  func checkNewIterator(c *C, buffer MemBuffer) {
    79  	for i := startIndex; i < testCount; i++ {
    80  		val := encodeInt(i * indexStep)
    81  		iter, err := buffer.Seek(val)
    82  		c.Assert(err, IsNil)
    83  		c.Assert([]byte(iter.Key()), BytesEquals, val)
    84  		c.Assert(decodeInt([]byte(valToStr(c, iter))), Equals, i*indexStep)
    85  		iter.Close()
    86  	}
    87  
    88  	// Test iterator Next()
    89  	for i := startIndex; i < testCount-1; i++ {
    90  		val := encodeInt(i * indexStep)
    91  		iter, err := buffer.Seek(val)
    92  		c.Assert(err, IsNil)
    93  		c.Assert([]byte(iter.Key()), BytesEquals, val)
    94  		c.Assert(valToStr(c, iter), Equals, string(val))
    95  
    96  		err = iter.Next()
    97  		c.Assert(err, IsNil)
    98  		c.Assert(iter.Valid(), IsTrue)
    99  
   100  		val = encodeInt((i + 1) * indexStep)
   101  		c.Assert([]byte(iter.Key()), BytesEquals, val)
   102  		c.Assert(valToStr(c, iter), Equals, string(val))
   103  		iter.Close()
   104  	}
   105  
   106  	// Non exist and beyond maximum seek test
   107  	iter, err := buffer.Seek(encodeInt(testCount * indexStep))
   108  	c.Assert(err, IsNil)
   109  	c.Assert(iter.Valid(), IsFalse)
   110  
   111  	// Non exist but between existing keys seek test,
   112  	// it returns the smallest key that larger than the one we are seeking
   113  	inBetween := encodeInt((testCount-1)*indexStep - 1)
   114  	last := encodeInt((testCount - 1) * indexStep)
   115  	iter, err = buffer.Seek(inBetween)
   116  	c.Assert(err, IsNil)
   117  	c.Assert(iter.Valid(), IsTrue)
   118  	c.Assert([]byte(iter.Key()), Not(BytesEquals), inBetween)
   119  	c.Assert([]byte(iter.Key()), BytesEquals, last)
   120  	iter.Close()
   121  }
   122  
   123  func mustNotGet(c *C, buffer MemBuffer) {
   124  	for i := startIndex; i < testCount; i++ {
   125  		s := encodeInt(i * indexStep)
   126  		_, err := buffer.Get(s)
   127  		c.Assert(err, NotNil)
   128  	}
   129  }
   130  
   131  func mustGet(c *C, buffer MemBuffer) {
   132  	for i := startIndex; i < testCount; i++ {
   133  		s := encodeInt(i * indexStep)
   134  		val, err := buffer.Get(s)
   135  		c.Assert(err, IsNil)
   136  		c.Assert(string(val), Equals, string(s))
   137  	}
   138  }
   139  
   140  func (s *testKVSuite) TestGetSet(c *C) {
   141  	defer testleak.AfterTest(c)()
   142  	for _, buffer := range s.bs {
   143  		insertData(c, buffer)
   144  		mustGet(c, buffer)
   145  		buffer.Release()
   146  	}
   147  }
   148  
   149  func (s *testKVSuite) TestNewIterator(c *C) {
   150  	defer testleak.AfterTest(c)()
   151  	for _, buffer := range s.bs {
   152  		// should be invalid
   153  		iter, err := buffer.Seek(nil)
   154  		c.Assert(err, IsNil)
   155  		c.Assert(iter.Valid(), IsFalse)
   156  
   157  		insertData(c, buffer)
   158  		checkNewIterator(c, buffer)
   159  		buffer.Release()
   160  	}
   161  }
   162  
   163  func (s *testKVSuite) TestBasicNewIterator(c *C) {
   164  	defer testleak.AfterTest(c)()
   165  	for _, buffer := range s.bs {
   166  		it, err := buffer.Seek([]byte("2"))
   167  		c.Assert(err, IsNil)
   168  		c.Assert(it.Valid(), IsFalse)
   169  		buffer.Release()
   170  	}
   171  }
   172  
   173  func (s *testKVSuite) TestNewIteratorMin(c *C) {
   174  	defer testleak.AfterTest(c)()
   175  	kvs := []struct {
   176  		key   string
   177  		value string
   178  	}{
   179  		{"DATA_test_main_db_tbl_tbl_test_record__00000000000000000001", "lock-version"},
   180  		{"DATA_test_main_db_tbl_tbl_test_record__00000000000000000001_0002", "1"},
   181  		{"DATA_test_main_db_tbl_tbl_test_record__00000000000000000001_0003", "hello"},
   182  		{"DATA_test_main_db_tbl_tbl_test_record__00000000000000000002", "lock-version"},
   183  		{"DATA_test_main_db_tbl_tbl_test_record__00000000000000000002_0002", "2"},
   184  		{"DATA_test_main_db_tbl_tbl_test_record__00000000000000000002_0003", "hello"},
   185  	}
   186  	for _, buffer := range s.bs {
   187  		for _, kv := range kvs {
   188  			buffer.Set([]byte(kv.key), []byte(kv.value))
   189  		}
   190  
   191  		cnt := 0
   192  		it, err := buffer.Seek(nil)
   193  		c.Assert(err, IsNil)
   194  		for it.Valid() {
   195  			cnt++
   196  			it.Next()
   197  		}
   198  		c.Assert(cnt, Equals, 6)
   199  
   200  		it, err = buffer.Seek([]byte("DATA_test_main_db_tbl_tbl_test_record__00000000000000000000"))
   201  		c.Assert(err, IsNil)
   202  		c.Assert(string(it.Key()), Equals, "DATA_test_main_db_tbl_tbl_test_record__00000000000000000001")
   203  
   204  		buffer.Release()
   205  	}
   206  }
   207  
   208  var opCnt = 100000
   209  
   210  func BenchmarkRBTreeBufferSequential(b *testing.B) {
   211  	data := make([][]byte, opCnt)
   212  	for i := 0; i < opCnt; i++ {
   213  		data[i] = encodeInt(i)
   214  	}
   215  	buffer := NewRBTreeBuffer()
   216  	benchmarkSetGet(b, buffer, data)
   217  	buffer.Release()
   218  	b.ReportAllocs()
   219  }
   220  
   221  func BenchmarkRBTreeBufferRandom(b *testing.B) {
   222  	data := make([][]byte, opCnt)
   223  	for i := 0; i < opCnt; i++ {
   224  		data[i] = encodeInt(i)
   225  	}
   226  	shuffle(data)
   227  	buffer := NewRBTreeBuffer()
   228  	benchmarkSetGet(b, buffer, data)
   229  	buffer.Release()
   230  	b.ReportAllocs()
   231  }
   232  
   233  func BenchmarkMemDbBufferSequential(b *testing.B) {
   234  	data := make([][]byte, opCnt)
   235  	for i := 0; i < opCnt; i++ {
   236  		data[i] = encodeInt(i)
   237  	}
   238  	buffer := NewMemDbBuffer()
   239  	benchmarkSetGet(b, buffer, data)
   240  	buffer.Release()
   241  	b.ReportAllocs()
   242  }
   243  
   244  func BenchmarkMemDbBufferRandom(b *testing.B) {
   245  	data := make([][]byte, opCnt)
   246  	for i := 0; i < opCnt; i++ {
   247  		data[i] = encodeInt(i)
   248  	}
   249  	shuffle(data)
   250  	buffer := NewMemDbBuffer()
   251  	benchmarkSetGet(b, buffer, data)
   252  	buffer.Release()
   253  	b.ReportAllocs()
   254  }
   255  
   256  func BenchmarkRBTreeIter(b *testing.B) {
   257  	buffer := NewRBTreeBuffer()
   258  	benchIterator(b, buffer)
   259  	buffer.Release()
   260  	b.ReportAllocs()
   261  }
   262  
   263  func BenchmarkMemDbIter(b *testing.B) {
   264  	buffer := NewMemDbBuffer()
   265  	benchIterator(b, buffer)
   266  	buffer.Release()
   267  	b.ReportAllocs()
   268  }
   269  
   270  func BenchmarkRBTreeCreation(b *testing.B) {
   271  	for i := 0; i < b.N; i++ {
   272  		buffer := NewRBTreeBuffer()
   273  		buffer.Release()
   274  	}
   275  	b.ReportAllocs()
   276  }
   277  
   278  func BenchmarkMemDbCreation(b *testing.B) {
   279  	for i := 0; i < b.N; i++ {
   280  		buffer := NewMemDbBuffer()
   281  		buffer.Release()
   282  	}
   283  	b.ReportAllocs()
   284  }
   285  
   286  func shuffle(slc [][]byte) {
   287  	N := len(slc)
   288  	for i := 0; i < N; i++ {
   289  		// choose index uniformly in [i, N-1]
   290  		r := i + rand.Intn(N-i)
   291  		slc[r], slc[i] = slc[i], slc[r]
   292  	}
   293  }
   294  func benchmarkSetGet(b *testing.B, buffer MemBuffer, data [][]byte) {
   295  	b.ResetTimer()
   296  	for i := 0; i < b.N; i++ {
   297  		for _, k := range data {
   298  			buffer.Set(k, k)
   299  		}
   300  		for _, k := range data {
   301  			buffer.Get(k)
   302  		}
   303  	}
   304  }
   305  
   306  func benchIterator(b *testing.B, buffer MemBuffer) {
   307  	for k := 0; k < opCnt; k++ {
   308  		buffer.Set(encodeInt(k), encodeInt(k))
   309  	}
   310  	b.ResetTimer()
   311  	for i := 0; i < b.N; i++ {
   312  		iter, err := buffer.Seek(nil)
   313  		if err != nil {
   314  			b.Error(err)
   315  		}
   316  		for iter.Valid() {
   317  			iter.Next()
   318  		}
   319  		iter.Close()
   320  	}
   321  }