github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/allegrosql/memdb_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Copyright 2020 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 ekv
    17  
    18  import (
    19  	"context"
    20  	"encoding/binary"
    21  	"fmt"
    22  	"math"
    23  	"testing"
    24  
    25  	. "github.com/whtcorpsinc/check"
    26  	leveldb "github.com/whtcorpsinc/goleveldb/leveldb/memdb"
    27  	"github.com/whtcorpsinc/milevadb/soliton/testleak"
    28  )
    29  
    30  func init() {
    31  	testMode = true
    32  }
    33  
    34  func TestT(t *testing.T) {
    35  	CustomVerboseFlag = true
    36  	TestingT(t)
    37  }
    38  
    39  var (
    40  	_ = Suite(&testKVSuite{})
    41  	_ = Suite(&testMemDBSuite{})
    42  )
    43  
    44  type testMemDBSuite struct{}
    45  
    46  // DeleteKey is used in test to verify the `deleteNode` used in `vlog.revertToCheckpoint`.
    47  func (EDB *memdb) DeleteKey(key []byte) {
    48  	x := EDB.traverse(key, false)
    49  	if x.isNull() {
    50  		return
    51  	}
    52  	EDB.size -= len(EDB.vlog.getValue(x.vptr))
    53  	EDB.deleteNode(x)
    54  }
    55  
    56  func (s *testMemDBSuite) TestGetSet(c *C) {
    57  	const cnt = 10000
    58  	p := s.fillDB(cnt)
    59  
    60  	var buf [4]byte
    61  	for i := 0; i < cnt; i++ {
    62  		binary.BigEndian.PutUint32(buf[:], uint32(i))
    63  		v, err := p.Get(context.TODO(), buf[:])
    64  		c.Assert(err, IsNil)
    65  		c.Assert(v, BytesEquals, buf[:])
    66  	}
    67  }
    68  
    69  func (s *testMemDBSuite) TestBigKV(c *C) {
    70  	EDB := newMemDB()
    71  	EDB.entrySizeLimit = math.MaxUint64
    72  	EDB.bufferSizeLimit = math.MaxUint64
    73  	EDB.Set([]byte{1}, make([]byte, 80<<20))
    74  	c.Assert(EDB.vlog.blockSize, Equals, maxBlockSize)
    75  	c.Assert(len(EDB.vlog.blocks), Equals, 1)
    76  	h := EDB.Staging()
    77  	EDB.Set([]byte{2}, make([]byte, 127<<20))
    78  	EDB.Release(h)
    79  	c.Assert(EDB.vlog.blockSize, Equals, maxBlockSize)
    80  	c.Assert(len(EDB.vlog.blocks), Equals, 2)
    81  	c.Assert(func() { EDB.Set([]byte{3}, make([]byte, maxBlockSize+1)) }, Panics, "alloc size is larger than max causet size")
    82  }
    83  
    84  func (s *testMemDBSuite) TestIterator(c *C) {
    85  	const cnt = 10000
    86  	EDB := s.fillDB(cnt)
    87  
    88  	var buf [4]byte
    89  	var i int
    90  
    91  	for it, _ := EDB.Iter(nil, nil); it.Valid(); it.Next() {
    92  		binary.BigEndian.PutUint32(buf[:], uint32(i))
    93  		c.Assert([]byte(it.Key()), BytesEquals, buf[:])
    94  		c.Assert(it.Value(), BytesEquals, buf[:])
    95  		i++
    96  	}
    97  	c.Assert(i, Equals, cnt)
    98  
    99  	i--
   100  	for it, _ := EDB.IterReverse(nil); it.Valid(); it.Next() {
   101  		binary.BigEndian.PutUint32(buf[:], uint32(i))
   102  		c.Assert([]byte(it.Key()), BytesEquals, buf[:])
   103  		c.Assert(it.Value(), BytesEquals, buf[:])
   104  		i--
   105  	}
   106  	c.Assert(i, Equals, -1)
   107  }
   108  
   109  func (s *testMemDBSuite) TestDiscard(c *C) {
   110  	const cnt = 10000
   111  	EDB := newMemDB()
   112  	base := s.deriveAndFill(0, cnt, 0, EDB)
   113  	sz := EDB.Size()
   114  
   115  	EDB.Cleanup(s.deriveAndFill(0, cnt, 1, EDB))
   116  	c.Assert(EDB.Len(), Equals, cnt)
   117  	c.Assert(EDB.Size(), Equals, sz)
   118  
   119  	var buf [4]byte
   120  
   121  	for i := 0; i < cnt; i++ {
   122  		binary.BigEndian.PutUint32(buf[:], uint32(i))
   123  		v, err := EDB.Get(context.TODO(), buf[:])
   124  		c.Assert(err, IsNil)
   125  		c.Assert(v, BytesEquals, buf[:])
   126  	}
   127  
   128  	var i int
   129  	for it, _ := EDB.Iter(nil, nil); it.Valid(); it.Next() {
   130  		binary.BigEndian.PutUint32(buf[:], uint32(i))
   131  		c.Assert([]byte(it.Key()), BytesEquals, buf[:])
   132  		c.Assert(it.Value(), BytesEquals, buf[:])
   133  		i++
   134  	}
   135  	c.Assert(i, Equals, cnt)
   136  
   137  	i--
   138  	for it, _ := EDB.IterReverse(nil); it.Valid(); it.Next() {
   139  		binary.BigEndian.PutUint32(buf[:], uint32(i))
   140  		c.Assert([]byte(it.Key()), BytesEquals, buf[:])
   141  		c.Assert(it.Value(), BytesEquals, buf[:])
   142  		i--
   143  	}
   144  	c.Assert(i, Equals, -1)
   145  
   146  	EDB.Cleanup(base)
   147  	for i := 0; i < cnt; i++ {
   148  		binary.BigEndian.PutUint32(buf[:], uint32(i))
   149  		_, err := EDB.Get(context.TODO(), buf[:])
   150  		c.Assert(err, NotNil)
   151  	}
   152  	it1, _ := EDB.Iter(nil, nil)
   153  	it := it1.(*memdbIterator)
   154  	it.seekToFirst()
   155  	c.Assert(it.Valid(), IsFalse)
   156  	it.seekToLast()
   157  	c.Assert(it.Valid(), IsFalse)
   158  	it.seek([]byte{0xff})
   159  	c.Assert(it.Valid(), IsFalse)
   160  }
   161  
   162  func (s *testMemDBSuite) TestFlushOverwrite(c *C) {
   163  	const cnt = 10000
   164  	EDB := newMemDB()
   165  	EDB.Release(s.deriveAndFill(0, cnt, 0, EDB))
   166  	sz := EDB.Size()
   167  
   168  	EDB.Release(s.deriveAndFill(0, cnt, 1, EDB))
   169  
   170  	c.Assert(EDB.Len(), Equals, cnt)
   171  	c.Assert(EDB.Size(), Equals, sz)
   172  
   173  	var kbuf, vbuf [4]byte
   174  
   175  	for i := 0; i < cnt; i++ {
   176  		binary.BigEndian.PutUint32(kbuf[:], uint32(i))
   177  		binary.BigEndian.PutUint32(vbuf[:], uint32(i+1))
   178  		v, err := EDB.Get(context.TODO(), kbuf[:])
   179  		c.Assert(err, IsNil)
   180  		c.Assert(v, DeepEquals, vbuf[:])
   181  	}
   182  
   183  	var i int
   184  	for it, _ := EDB.Iter(nil, nil); it.Valid(); it.Next() {
   185  		binary.BigEndian.PutUint32(kbuf[:], uint32(i))
   186  		binary.BigEndian.PutUint32(vbuf[:], uint32(i+1))
   187  		c.Assert([]byte(it.Key()), BytesEquals, kbuf[:])
   188  		c.Assert(it.Value(), BytesEquals, vbuf[:])
   189  		i++
   190  	}
   191  	c.Assert(i, Equals, cnt)
   192  
   193  	i--
   194  	for it, _ := EDB.IterReverse(nil); it.Valid(); it.Next() {
   195  		binary.BigEndian.PutUint32(kbuf[:], uint32(i))
   196  		binary.BigEndian.PutUint32(vbuf[:], uint32(i+1))
   197  		c.Assert([]byte(it.Key()), BytesEquals, kbuf[:])
   198  		c.Assert(it.Value(), BytesEquals, vbuf[:])
   199  		i--
   200  	}
   201  	c.Assert(i, Equals, -1)
   202  }
   203  
   204  func (s *testMemDBSuite) TestComplexUFIDelate(c *C) {
   205  	const (
   206  		keep      = 3000
   207  		overwrite = 6000
   208  		insert    = 9000
   209  	)
   210  
   211  	EDB := newMemDB()
   212  	EDB.Release(s.deriveAndFill(0, overwrite, 0, EDB))
   213  	c.Assert(EDB.Len(), Equals, overwrite)
   214  	EDB.Release(s.deriveAndFill(keep, insert, 1, EDB))
   215  	c.Assert(EDB.Len(), Equals, insert)
   216  
   217  	var kbuf, vbuf [4]byte
   218  
   219  	for i := 0; i < insert; i++ {
   220  		binary.BigEndian.PutUint32(kbuf[:], uint32(i))
   221  		binary.BigEndian.PutUint32(vbuf[:], uint32(i))
   222  		if i >= keep {
   223  			binary.BigEndian.PutUint32(vbuf[:], uint32(i+1))
   224  		}
   225  		v, err := EDB.Get(context.TODO(), kbuf[:])
   226  		c.Assert(err, IsNil)
   227  		c.Assert(v, BytesEquals, vbuf[:])
   228  	}
   229  }
   230  
   231  func (s *testMemDBSuite) TestNestedSandbox(c *C) {
   232  	EDB := newMemDB()
   233  	h0 := s.deriveAndFill(0, 200, 0, EDB)
   234  	h1 := s.deriveAndFill(0, 100, 1, EDB)
   235  	h2 := s.deriveAndFill(50, 150, 2, EDB)
   236  	h3 := s.deriveAndFill(100, 120, 3, EDB)
   237  	h4 := s.deriveAndFill(0, 150, 4, EDB)
   238  	EDB.Cleanup(h4) // Discard (0..150 -> 4)
   239  	EDB.Release(h3) // Flush (100..120 -> 3)
   240  	EDB.Cleanup(h2) // Discard (100..120 -> 3) & (50..150 -> 2)
   241  	EDB.Release(h1) // Flush (0..100 -> 1)
   242  	EDB.Release(h0) // Flush (0..100 -> 1) & (0..200 -> 0)
   243  	// The final result should be (0..100 -> 1) & (101..200 -> 0)
   244  
   245  	var kbuf, vbuf [4]byte
   246  
   247  	for i := 0; i < 200; i++ {
   248  		binary.BigEndian.PutUint32(kbuf[:], uint32(i))
   249  		binary.BigEndian.PutUint32(vbuf[:], uint32(i))
   250  		if i < 100 {
   251  			binary.BigEndian.PutUint32(vbuf[:], uint32(i+1))
   252  		}
   253  		v, err := EDB.Get(context.TODO(), kbuf[:])
   254  		c.Assert(err, IsNil)
   255  		c.Assert(v, BytesEquals, vbuf[:])
   256  	}
   257  
   258  	var i int
   259  
   260  	for it, _ := EDB.Iter(nil, nil); it.Valid(); it.Next() {
   261  		binary.BigEndian.PutUint32(kbuf[:], uint32(i))
   262  		binary.BigEndian.PutUint32(vbuf[:], uint32(i))
   263  		if i < 100 {
   264  			binary.BigEndian.PutUint32(vbuf[:], uint32(i+1))
   265  		}
   266  		c.Assert([]byte(it.Key()), BytesEquals, kbuf[:])
   267  		c.Assert(it.Value(), BytesEquals, vbuf[:])
   268  		i++
   269  	}
   270  	c.Assert(i, Equals, 200)
   271  
   272  	i--
   273  	for it, _ := EDB.IterReverse(nil); it.Valid(); it.Next() {
   274  		binary.BigEndian.PutUint32(kbuf[:], uint32(i))
   275  		binary.BigEndian.PutUint32(vbuf[:], uint32(i))
   276  		if i < 100 {
   277  			binary.BigEndian.PutUint32(vbuf[:], uint32(i+1))
   278  		}
   279  		c.Assert([]byte(it.Key()), BytesEquals, kbuf[:])
   280  		c.Assert(it.Value(), BytesEquals, vbuf[:])
   281  		i--
   282  	}
   283  	c.Assert(i, Equals, -1)
   284  }
   285  
   286  func (s *testMemDBSuite) TestOverwrite(c *C) {
   287  	const cnt = 10000
   288  	EDB := s.fillDB(cnt)
   289  	var buf [4]byte
   290  
   291  	sz := EDB.Size()
   292  	for i := 0; i < cnt; i += 3 {
   293  		var newBuf [4]byte
   294  		binary.BigEndian.PutUint32(buf[:], uint32(i))
   295  		binary.BigEndian.PutUint32(newBuf[:], uint32(i*10))
   296  		EDB.Set(buf[:], newBuf[:])
   297  	}
   298  	c.Assert(EDB.Len(), Equals, cnt)
   299  	c.Assert(EDB.Size(), Equals, sz)
   300  
   301  	for i := 0; i < cnt; i++ {
   302  		binary.BigEndian.PutUint32(buf[:], uint32(i))
   303  		val, _ := EDB.Get(context.TODO(), buf[:])
   304  		v := binary.BigEndian.Uint32(val)
   305  		if i%3 == 0 {
   306  			c.Assert(v, Equals, uint32(i*10))
   307  		} else {
   308  			c.Assert(v, Equals, uint32(i))
   309  		}
   310  	}
   311  
   312  	var i int
   313  
   314  	for it, _ := EDB.Iter(nil, nil); it.Valid(); it.Next() {
   315  		binary.BigEndian.PutUint32(buf[:], uint32(i))
   316  		c.Assert([]byte(it.Key()), BytesEquals, buf[:])
   317  		v := binary.BigEndian.Uint32(it.Value())
   318  		if i%3 == 0 {
   319  			c.Assert(v, Equals, uint32(i*10))
   320  		} else {
   321  			c.Assert(v, Equals, uint32(i))
   322  		}
   323  		i++
   324  	}
   325  	c.Assert(i, Equals, cnt)
   326  
   327  	i--
   328  	for it, _ := EDB.IterReverse(nil); it.Valid(); it.Next() {
   329  		binary.BigEndian.PutUint32(buf[:], uint32(i))
   330  		c.Assert([]byte(it.Key()), BytesEquals, buf[:])
   331  		v := binary.BigEndian.Uint32(it.Value())
   332  		if i%3 == 0 {
   333  			c.Assert(v, Equals, uint32(i*10))
   334  		} else {
   335  			c.Assert(v, Equals, uint32(i))
   336  		}
   337  		i--
   338  	}
   339  	c.Assert(i, Equals, -1)
   340  }
   341  
   342  func (s *testMemDBSuite) TestKVLargeThanBlock(c *C) {
   343  	EDB := newMemDB()
   344  	EDB.Set([]byte{1}, make([]byte, 1))
   345  	EDB.Set([]byte{2}, make([]byte, 4096))
   346  	c.Assert(len(EDB.vlog.blocks), Equals, 2)
   347  	EDB.Set([]byte{3}, make([]byte, 3000))
   348  	c.Assert(len(EDB.vlog.blocks), Equals, 2)
   349  	val, err := EDB.Get(context.TODO(), []byte{3})
   350  	c.Assert(err, IsNil)
   351  	c.Assert(len(val), Equals, 3000)
   352  }
   353  
   354  func (s *testMemDBSuite) TestEmptyDB(c *C) {
   355  	EDB := newMemDB()
   356  	_, err := EDB.Get(context.TODO(), []byte{0})
   357  	c.Assert(err, NotNil)
   358  	it1, _ := EDB.Iter(nil, nil)
   359  	it := it1.(*memdbIterator)
   360  	it.seekToFirst()
   361  	c.Assert(it.Valid(), IsFalse)
   362  	it.seekToLast()
   363  	c.Assert(it.Valid(), IsFalse)
   364  	it.seek([]byte{0xff})
   365  	c.Assert(it.Valid(), IsFalse)
   366  }
   367  
   368  func (s *testMemDBSuite) TestReset(c *C) {
   369  	EDB := s.fillDB(1000)
   370  	EDB.Reset()
   371  	_, err := EDB.Get(context.TODO(), []byte{0, 0, 0, 0})
   372  	c.Assert(err, NotNil)
   373  	it1, _ := EDB.Iter(nil, nil)
   374  	it := it1.(*memdbIterator)
   375  	it.seekToFirst()
   376  	c.Assert(it.Valid(), IsFalse)
   377  	it.seekToLast()
   378  	c.Assert(it.Valid(), IsFalse)
   379  	it.seek([]byte{0xff})
   380  	c.Assert(it.Valid(), IsFalse)
   381  }
   382  
   383  func (s *testMemDBSuite) TestInspectStage(c *C) {
   384  	EDB := newMemDB()
   385  	h1 := s.deriveAndFill(0, 1000, 0, EDB)
   386  	h2 := s.deriveAndFill(500, 1000, 1, EDB)
   387  	for i := 500; i < 1500; i++ {
   388  		var kbuf [4]byte
   389  		// don't uFIDelate in place
   390  		var vbuf [5]byte
   391  		binary.BigEndian.PutUint32(kbuf[:], uint32(i))
   392  		binary.BigEndian.PutUint32(vbuf[:], uint32(i+2))
   393  		EDB.Set(kbuf[:], vbuf[:])
   394  	}
   395  	h3 := s.deriveAndFill(1000, 2000, 3, EDB)
   396  
   397  	EDB.InspectStage(h3, func(key Key, _ KeyFlags, val []byte) {
   398  		k := int(binary.BigEndian.Uint32(key))
   399  		v := int(binary.BigEndian.Uint32(val))
   400  
   401  		c.Assert(k >= 1000 && k < 2000, IsTrue)
   402  		c.Assert(v-k, DeepEquals, 3)
   403  	})
   404  
   405  	EDB.InspectStage(h2, func(key Key, _ KeyFlags, val []byte) {
   406  		k := int(binary.BigEndian.Uint32(key))
   407  		v := int(binary.BigEndian.Uint32(val))
   408  
   409  		c.Assert(k >= 500 && k < 2000, IsTrue)
   410  		if k < 1000 {
   411  			c.Assert(v-k, Equals, 2)
   412  		} else {
   413  			c.Assert(v-k, Equals, 3)
   414  		}
   415  	})
   416  
   417  	EDB.Cleanup(h3)
   418  	EDB.Release(h2)
   419  
   420  	EDB.InspectStage(h1, func(key Key, _ KeyFlags, val []byte) {
   421  		k := int(binary.BigEndian.Uint32(key))
   422  		v := int(binary.BigEndian.Uint32(val))
   423  
   424  		c.Assert(k >= 0 && k < 1500, IsTrue)
   425  		if k < 500 {
   426  			c.Assert(v-k, Equals, 0)
   427  		} else {
   428  			c.Assert(v-k, Equals, 2)
   429  		}
   430  	})
   431  
   432  	EDB.Release(h1)
   433  }
   434  
   435  func (s *testMemDBSuite) TestDirty(c *C) {
   436  	EDB := newMemDB()
   437  	EDB.Set([]byte{1}, []byte{1})
   438  	c.Assert(EDB.Dirty(), IsTrue)
   439  
   440  	EDB = newMemDB()
   441  	h := EDB.Staging()
   442  	EDB.Set([]byte{1}, []byte{1})
   443  	EDB.Cleanup(h)
   444  	c.Assert(EDB.Dirty(), IsFalse)
   445  
   446  	h = EDB.Staging()
   447  	EDB.Set([]byte{1}, []byte{1})
   448  	EDB.Release(h)
   449  	c.Assert(EDB.Dirty(), IsTrue)
   450  
   451  	// persistent flags will make memdb dirty.
   452  	EDB = newMemDB()
   453  	h = EDB.Staging()
   454  	EDB.SetWithFlags([]byte{1}, []byte{1}, SetKeyLocked)
   455  	EDB.Cleanup(h)
   456  	c.Assert(EDB.Dirty(), IsTrue)
   457  
   458  	// non-persistent flags will not make memdb dirty.
   459  	EDB = newMemDB()
   460  	h = EDB.Staging()
   461  	EDB.SetWithFlags([]byte{1}, []byte{1}, SetPresumeKeyNotExists)
   462  	EDB.Cleanup(h)
   463  	c.Assert(EDB.Dirty(), IsFalse)
   464  }
   465  
   466  func (s *testMemDBSuite) TestFlags(c *C) {
   467  	const cnt = 10000
   468  	EDB := newMemDB()
   469  	h := EDB.Staging()
   470  	for i := uint32(0); i < cnt; i++ {
   471  		var buf [4]byte
   472  		binary.BigEndian.PutUint32(buf[:], i)
   473  		if i%2 == 0 {
   474  			EDB.SetWithFlags(buf[:], buf[:], SetPresumeKeyNotExists, SetKeyLocked)
   475  		} else {
   476  			EDB.SetWithFlags(buf[:], buf[:], SetPresumeKeyNotExists)
   477  		}
   478  	}
   479  	EDB.Cleanup(h)
   480  
   481  	for i := uint32(0); i < cnt; i++ {
   482  		var buf [4]byte
   483  		binary.BigEndian.PutUint32(buf[:], i)
   484  		_, err := EDB.Get(context.TODO(), buf[:])
   485  		c.Assert(err, NotNil)
   486  		flags, err := EDB.GetFlags(buf[:])
   487  		if i%2 == 0 {
   488  			c.Assert(err, IsNil)
   489  			c.Assert(flags.HasLocked(), IsTrue)
   490  			c.Assert(flags.HasPresumeKeyNotExists(), IsFalse)
   491  		} else {
   492  			c.Assert(err, NotNil)
   493  		}
   494  	}
   495  
   496  	c.Assert(EDB.Len(), Equals, 5000)
   497  	c.Assert(EDB.Size(), Equals, 20000)
   498  
   499  	it1, _ := EDB.Iter(nil, nil)
   500  	it := it1.(*memdbIterator)
   501  	c.Assert(it.Valid(), IsFalse)
   502  
   503  	it.includeFlags = true
   504  	it.init()
   505  
   506  	for ; it.Valid(); it.Next() {
   507  		k := binary.BigEndian.Uint32(it.Key())
   508  		c.Assert(k%2 == 0, IsTrue)
   509  	}
   510  
   511  	for i := uint32(0); i < cnt; i++ {
   512  		var buf [4]byte
   513  		binary.BigEndian.PutUint32(buf[:], i)
   514  		EDB.UFIDelateFlags(buf[:], DelKeyLocked)
   515  	}
   516  	for i := uint32(0); i < cnt; i++ {
   517  		var buf [4]byte
   518  		binary.BigEndian.PutUint32(buf[:], i)
   519  		_, err := EDB.Get(context.TODO(), buf[:])
   520  		c.Assert(err, NotNil)
   521  
   522  		// UFIDelateFlags will create missing node.
   523  		flags, err := EDB.GetFlags(buf[:])
   524  		c.Assert(err, IsNil)
   525  		c.Assert(flags.HasLocked(), IsFalse)
   526  	}
   527  }
   528  
   529  func (s *testMemDBSuite) checkConsist(c *C, p1 *memdb, p2 *leveldb.EDB) {
   530  	c.Assert(p1.Len(), Equals, p2.Len())
   531  	c.Assert(p1.Size(), Equals, p2.Size())
   532  
   533  	it1, _ := p1.Iter(nil, nil)
   534  	it2 := p2.NewIterator(nil)
   535  
   536  	var prevKey, prevVal []byte
   537  	for it2.First(); it2.Valid(); it2.Next() {
   538  		v, err := p1.Get(context.TODO(), it2.Key())
   539  		c.Assert(err, IsNil)
   540  		c.Assert(v, BytesEquals, it2.Value())
   541  
   542  		c.Assert([]byte(it1.Key()), BytesEquals, it2.Key())
   543  		c.Assert(it1.Value(), BytesEquals, it2.Value())
   544  
   545  		it, _ := p1.Iter(it2.Key(), nil)
   546  		c.Assert([]byte(it.Key()), BytesEquals, it2.Key())
   547  		c.Assert(it.Value(), BytesEquals, it2.Value())
   548  
   549  		if prevKey != nil {
   550  			it, _ = p1.IterReverse(it2.Key())
   551  			c.Assert([]byte(it.Key()), BytesEquals, prevKey)
   552  			c.Assert(it.Value(), BytesEquals, prevVal)
   553  		}
   554  
   555  		it1.Next()
   556  		prevKey = it2.Key()
   557  		prevVal = it2.Value()
   558  	}
   559  
   560  	it1, _ = p1.IterReverse(nil)
   561  	for it2.Last(); it2.Valid(); it2.Prev() {
   562  		c.Assert([]byte(it1.Key()), BytesEquals, it2.Key())
   563  		c.Assert(it1.Value(), BytesEquals, it2.Value())
   564  		it1.Next()
   565  	}
   566  }
   567  
   568  func (s *testMemDBSuite) fillDB(cnt int) *memdb {
   569  	EDB := newMemDB()
   570  	h := s.deriveAndFill(0, cnt, 0, EDB)
   571  	EDB.Release(h)
   572  	return EDB
   573  }
   574  
   575  func (s *testMemDBSuite) deriveAndFill(start, end, valueBase int, EDB *memdb) StagingHandle {
   576  	h := EDB.Staging()
   577  	var kbuf, vbuf [4]byte
   578  	for i := start; i < end; i++ {
   579  		binary.BigEndian.PutUint32(kbuf[:], uint32(i))
   580  		binary.BigEndian.PutUint32(vbuf[:], uint32(i+valueBase))
   581  		EDB.Set(kbuf[:], vbuf[:])
   582  	}
   583  	return h
   584  }
   585  
   586  const (
   587  	startIndex = 0
   588  	testCount  = 2
   589  	indexStep  = 2
   590  )
   591  
   592  type testKVSuite struct {
   593  	bs []MemBuffer
   594  }
   595  
   596  func (s *testKVSuite) SetUpSuite(c *C) {
   597  	s.bs = make([]MemBuffer, 1)
   598  	s.bs[0] = newMemDB()
   599  }
   600  
   601  func (s *testKVSuite) ResetMembuffers() {
   602  	s.bs[0] = newMemDB()
   603  }
   604  
   605  func insertData(c *C, buffer MemBuffer) {
   606  	for i := startIndex; i < testCount; i++ {
   607  		val := encodeInt(i * indexStep)
   608  		err := buffer.Set(val, val)
   609  		c.Assert(err, IsNil)
   610  	}
   611  }
   612  
   613  func encodeInt(n int) []byte {
   614  	return []byte(fmt.Sprintf("%010d", n))
   615  }
   616  
   617  func decodeInt(s []byte) int {
   618  	var n int
   619  	fmt.Sscanf(string(s), "%010d", &n)
   620  	return n
   621  }
   622  
   623  func valToStr(c *C, iter Iterator) string {
   624  	val := iter.Value()
   625  	return string(val)
   626  }
   627  
   628  func checkNewIterator(c *C, buffer MemBuffer) {
   629  	for i := startIndex; i < testCount; i++ {
   630  		val := encodeInt(i * indexStep)
   631  		iter, err := buffer.Iter(val, nil)
   632  		c.Assert(err, IsNil)
   633  		c.Assert([]byte(iter.Key()), BytesEquals, val)
   634  		c.Assert(decodeInt([]byte(valToStr(c, iter))), Equals, i*indexStep)
   635  		iter.Close()
   636  	}
   637  
   638  	// Test iterator Next()
   639  	for i := startIndex; i < testCount-1; i++ {
   640  		val := encodeInt(i * indexStep)
   641  		iter, err := buffer.Iter(val, nil)
   642  		c.Assert(err, IsNil)
   643  		c.Assert([]byte(iter.Key()), BytesEquals, val)
   644  		c.Assert(valToStr(c, iter), Equals, string(val))
   645  
   646  		err = iter.Next()
   647  		c.Assert(err, IsNil)
   648  		c.Assert(iter.Valid(), IsTrue)
   649  
   650  		val = encodeInt((i + 1) * indexStep)
   651  		c.Assert([]byte(iter.Key()), BytesEquals, val)
   652  		c.Assert(valToStr(c, iter), Equals, string(val))
   653  		iter.Close()
   654  	}
   655  
   656  	// Non exist and beyond maximum seek test
   657  	iter, err := buffer.Iter(encodeInt(testCount*indexStep), nil)
   658  	c.Assert(err, IsNil)
   659  	c.Assert(iter.Valid(), IsFalse)
   660  
   661  	// Non exist but between existing keys seek test,
   662  	// it returns the smallest key that larger than the one we are seeking
   663  	inBetween := encodeInt((testCount-1)*indexStep - 1)
   664  	last := encodeInt((testCount - 1) * indexStep)
   665  	iter, err = buffer.Iter(inBetween, nil)
   666  	c.Assert(err, IsNil)
   667  	c.Assert(iter.Valid(), IsTrue)
   668  	c.Assert([]byte(iter.Key()), Not(BytesEquals), inBetween)
   669  	c.Assert([]byte(iter.Key()), BytesEquals, last)
   670  	iter.Close()
   671  }
   672  
   673  func mustGet(c *C, buffer MemBuffer) {
   674  	for i := startIndex; i < testCount; i++ {
   675  		s := encodeInt(i * indexStep)
   676  		val, err := buffer.Get(context.TODO(), s)
   677  		c.Assert(err, IsNil)
   678  		c.Assert(string(val), Equals, string(s))
   679  	}
   680  }
   681  
   682  func (s *testKVSuite) TestGetSet(c *C) {
   683  	defer testleak.AfterTest(c)()
   684  	for _, buffer := range s.bs {
   685  		insertData(c, buffer)
   686  		mustGet(c, buffer)
   687  	}
   688  	s.ResetMembuffers()
   689  }
   690  
   691  func (s *testKVSuite) TestNewIterator(c *C) {
   692  	defer testleak.AfterTest(c)()
   693  	for _, buffer := range s.bs {
   694  		// should be invalid
   695  		iter, err := buffer.Iter(nil, nil)
   696  		c.Assert(err, IsNil)
   697  		c.Assert(iter.Valid(), IsFalse)
   698  
   699  		insertData(c, buffer)
   700  		checkNewIterator(c, buffer)
   701  	}
   702  	s.ResetMembuffers()
   703  }
   704  
   705  func (s *testKVSuite) TestIterNextUntil(c *C) {
   706  	defer testleak.AfterTest(c)()
   707  	buffer := newMemDB()
   708  	insertData(c, buffer)
   709  
   710  	iter, err := buffer.Iter(nil, nil)
   711  	c.Assert(err, IsNil)
   712  
   713  	err = NextUntil(iter, func(k Key) bool {
   714  		return false
   715  	})
   716  	c.Assert(err, IsNil)
   717  	c.Assert(iter.Valid(), IsFalse)
   718  }
   719  
   720  func (s *testKVSuite) TestBasicNewIterator(c *C) {
   721  	defer testleak.AfterTest(c)()
   722  	for _, buffer := range s.bs {
   723  		it, err := buffer.Iter([]byte("2"), nil)
   724  		c.Assert(err, IsNil)
   725  		c.Assert(it.Valid(), IsFalse)
   726  	}
   727  }
   728  
   729  func (s *testKVSuite) TestNewIteratorMin(c *C) {
   730  	defer testleak.AfterTest(c)()
   731  	ekvs := []struct {
   732  		key   string
   733  		value string
   734  	}{
   735  		{"DATA_test_main_db_tbl_tbl_test_record__00000000000000000001", "dagger-version"},
   736  		{"DATA_test_main_db_tbl_tbl_test_record__00000000000000000001_0002", "1"},
   737  		{"DATA_test_main_db_tbl_tbl_test_record__00000000000000000001_0003", "hello"},
   738  		{"DATA_test_main_db_tbl_tbl_test_record__00000000000000000002", "dagger-version"},
   739  		{"DATA_test_main_db_tbl_tbl_test_record__00000000000000000002_0002", "2"},
   740  		{"DATA_test_main_db_tbl_tbl_test_record__00000000000000000002_0003", "hello"},
   741  	}
   742  	for _, buffer := range s.bs {
   743  		for _, ekv := range ekvs {
   744  			err := buffer.Set([]byte(ekv.key), []byte(ekv.value))
   745  			c.Assert(err, IsNil)
   746  		}
   747  
   748  		cnt := 0
   749  		it, err := buffer.Iter(nil, nil)
   750  		c.Assert(err, IsNil)
   751  		for it.Valid() {
   752  			cnt++
   753  			err := it.Next()
   754  			c.Assert(err, IsNil)
   755  		}
   756  		c.Assert(cnt, Equals, 6)
   757  
   758  		it, err = buffer.Iter([]byte("DATA_test_main_db_tbl_tbl_test_record__00000000000000000000"), nil)
   759  		c.Assert(err, IsNil)
   760  		c.Assert(string([]byte(it.Key())), Equals, "DATA_test_main_db_tbl_tbl_test_record__00000000000000000001")
   761  	}
   762  	s.ResetMembuffers()
   763  }
   764  
   765  func (s *testKVSuite) TestMemDBStaging(c *C) {
   766  	buffer := newMemDB()
   767  	err := buffer.Set([]byte("x"), make([]byte, 2))
   768  	c.Assert(err, IsNil)
   769  
   770  	h1 := buffer.Staging()
   771  	err = buffer.Set([]byte("x"), make([]byte, 3))
   772  	c.Assert(err, IsNil)
   773  
   774  	h2 := buffer.Staging()
   775  	err = buffer.Set([]byte("yz"), make([]byte, 1))
   776  	c.Assert(err, IsNil)
   777  
   778  	v, _ := buffer.Get(context.Background(), []byte("x"))
   779  	c.Assert(len(v), Equals, 3)
   780  
   781  	buffer.Release(h2)
   782  
   783  	v, _ = buffer.Get(context.Background(), []byte("yz"))
   784  	c.Assert(len(v), Equals, 1)
   785  
   786  	buffer.Cleanup(h1)
   787  
   788  	v, _ = buffer.Get(context.Background(), []byte("x"))
   789  	c.Assert(len(v), Equals, 2)
   790  }
   791  
   792  func (s *testKVSuite) TestBufferLimit(c *C) {
   793  	buffer := newMemDB()
   794  	buffer.bufferSizeLimit = 1000
   795  	buffer.entrySizeLimit = 500
   796  
   797  	err := buffer.Set([]byte("x"), make([]byte, 500))
   798  	c.Assert(err, NotNil) // entry size limit
   799  
   800  	err = buffer.Set([]byte("x"), make([]byte, 499))
   801  	c.Assert(err, IsNil)
   802  	err = buffer.Set([]byte("yz"), make([]byte, 499))
   803  	c.Assert(err, NotNil) // buffer size limit
   804  
   805  	err = buffer.Delete(make([]byte, 499))
   806  	c.Assert(err, IsNil)
   807  
   808  	err = buffer.Delete(make([]byte, 500))
   809  	c.Assert(err, NotNil)
   810  }
   811  
   812  func (s *testKVSuite) TestBufferBatchGetter(c *C) {
   813  	snap := &mockSnapshot{causetstore: newMemDB()}
   814  	ka := []byte("a")
   815  	kb := []byte("b")
   816  	kc := []byte("c")
   817  	kd := []byte("d")
   818  	snap.causetstore.Set(ka, ka)
   819  	snap.causetstore.Set(kb, kb)
   820  	snap.causetstore.Set(kc, kc)
   821  	snap.causetstore.Set(kd, kd)
   822  
   823  	// midbse value is the same as snap
   824  	midbse := newMemDB()
   825  	midbse.Set(ka, []byte("a1"))
   826  	midbse.Set(kc, []byte("c1"))
   827  
   828  	buffer := newMemDB()
   829  	buffer.Set(ka, []byte("a2"))
   830  	buffer.Delete(kb)
   831  
   832  	batchGetter := NewBufferBatchGetter(buffer, midbse, snap)
   833  	result, err := batchGetter.BatchGet(context.Background(), []Key{ka, kb, kc, kd})
   834  	c.Assert(err, IsNil)
   835  	c.Assert(len(result), Equals, 3)
   836  	c.Assert(string(result[string(ka)]), Equals, "a2")
   837  	c.Assert(string(result[string(kc)]), Equals, "c1")
   838  	c.Assert(string(result[string(kd)]), Equals, "d")
   839  }