github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitpage/bitpage_test.go (about)

     1  // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package bitpage
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"math/rand"
    21  	"os"
    22  	"sync"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/stretchr/testify/require"
    27  	"github.com/zuoyebang/bitalosdb/internal/consts"
    28  	"github.com/zuoyebang/bitalosdb/internal/hash"
    29  	"github.com/zuoyebang/bitalosdb/internal/options"
    30  	"github.com/zuoyebang/bitalosdb/internal/sortedkv"
    31  	"github.com/zuoyebang/bitalosdb/internal/utils"
    32  )
    33  
    34  const testDir = "test"
    35  const testSlotId uint16 = 1
    36  
    37  var nilInternalKey = (*internalKey)(nil)
    38  
    39  var testParams = [][]bool{
    40  	{true, false, false},
    41  	{true, true, false},
    42  	{true, false, true},
    43  	{true, true, true},
    44  }
    45  
    46  func testMakeSortedKV(num int, seqNum uint64, vsize int) sortedkv.SortedKVList {
    47  	return sortedkv.MakeSortedKVList(0, num, seqNum, vsize)
    48  }
    49  
    50  func testMakeSortedKVForBitrie(num int, seqNum uint64, vsize int) sortedkv.SortedKVList {
    51  	return sortedkv.MakeSortedKVListForBitrie(0, num, seqNum, vsize)
    52  }
    53  
    54  func testInitDir() {
    55  	_, err := os.Stat(testDir)
    56  	if nil != err && !os.IsExist(err) {
    57  		err = os.MkdirAll(testDir, 0775)
    58  	}
    59  }
    60  
    61  func testInitOpts() *options.BitpageOptions {
    62  	optspool := options.InitTestDefaultsOptionsPool()
    63  	opts := optspool.CloneBitpageOptions()
    64  	return opts
    65  }
    66  
    67  func testOpenBitpage(UseMapIndex bool) (*Bitpage, error) {
    68  	testInitDir()
    69  	opts := testInitOpts()
    70  	opts.Index = 1
    71  	opts.UseMapIndex = UseMapIndex
    72  	return Open(testDir, opts)
    73  }
    74  
    75  func testOpenBitpage2(dir string, mapIndex, prefix, block bool) (*Bitpage, error) {
    76  	testInitDir()
    77  	opts := testInitOpts()
    78  	opts.Index = 1
    79  	opts.UseMapIndex = mapIndex
    80  	opts.UsePrefixCompress = prefix
    81  	opts.UseBlockCompress = block
    82  	return Open(dir, opts)
    83  }
    84  
    85  func testCloseBitpage(t *testing.T, b *Bitpage) {
    86  	require.NoError(t, b.Close())
    87  	b.opts.DeleteFilePacer.Close()
    88  }
    89  
    90  func makeTestKey(i int) []byte {
    91  	return []byte(fmt.Sprintf("bitpage_key_%d", i))
    92  }
    93  
    94  func TestBitpage_Open(t *testing.T) {
    95  	defer os.RemoveAll(testDir)
    96  	os.RemoveAll(testDir)
    97  	bp, err := testOpenBitpage(true)
    98  	require.NoError(t, err)
    99  	pn, err1 := bp.NewPage()
   100  	require.NoError(t, err1)
   101  	p := bp.GetPage(pn)
   102  	paths := p.getFilesPath()
   103  	testCloseBitpage(t, bp)
   104  
   105  	bp, err = testOpenBitpage(true)
   106  	require.NoError(t, err)
   107  	for i := range paths {
   108  		require.Equal(t, true, utils.IsFileExist(paths[i]))
   109  	}
   110  	testCloseBitpage(t, bp)
   111  }
   112  
   113  func TestBitpage_Writer(t *testing.T) {
   114  	defer os.RemoveAll(testDir)
   115  	os.RemoveAll(testDir)
   116  
   117  	bp, err := testOpenBitpage(true)
   118  	require.NoError(t, err)
   119  
   120  	pn, err1 := bp.NewPage()
   121  	require.NoError(t, err1)
   122  
   123  	count := 1000
   124  	seqNum := uint64(1)
   125  	kvList := testMakeSortedKV(count, seqNum, 10)
   126  	seqNum += uint64(count)
   127  
   128  	wr := bp.GetPageWriter(pn, nil)
   129  	writeKV := func(pos int) {
   130  		require.NoError(t, wr.Set(*kvList[pos].Key, kvList[pos].Value))
   131  	}
   132  
   133  	for i := 0; i < count; i++ {
   134  		if i >= 10 && i < 20 {
   135  			kvList[i].Key.SetKind(internalKeyKindDelete)
   136  		}
   137  		writeKV(i)
   138  	}
   139  	require.NoError(t, wr.FlushFinish())
   140  
   141  	p := bp.GetPage(pn)
   142  	for i := 0; i < count; i++ {
   143  		uk := kvList[i].Key.UserKey
   144  		v, vexist, vcloser, kind := p.get(uk, hash.Crc32(uk))
   145  		if i >= 10 && i < 20 {
   146  			require.Equal(t, false, vexist)
   147  			require.Equal(t, internalKeyKindDelete, kind)
   148  		} else {
   149  			require.Equal(t, kvList[i].Value, v)
   150  			require.Equal(t, internalKeyKindSet, kind)
   151  		}
   152  		if vcloser != nil {
   153  			vcloser()
   154  		}
   155  	}
   156  
   157  	for i := 10; i < 20; i++ {
   158  		kvList[i].Key.SetKind(internalKeyKindSet)
   159  		kvList[i].Key.SetSeqNum(seqNum)
   160  		seqNum++
   161  		writeKV(i)
   162  	}
   163  	require.NoError(t, wr.FlushFinish())
   164  
   165  	for i := 0; i < count; i++ {
   166  		uk := kvList[i].Key.UserKey
   167  		v, vexist, vcloser, kind := p.get(uk, hash.Crc32(uk))
   168  		require.Equal(t, true, vexist)
   169  		require.Equal(t, kvList[i].Value, v)
   170  		require.Equal(t, internalKeyKindSet, kind)
   171  		vcloser()
   172  	}
   173  
   174  	testCloseBitpage(t, bp)
   175  }
   176  
   177  func TestBitpage_StMmapExpand(t *testing.T) {
   178  	defer os.RemoveAll(testDir)
   179  	os.RemoveAll(testDir)
   180  
   181  	bp, err := testOpenBitpage(true)
   182  	require.NoError(t, err)
   183  	pn, err1 := bp.NewPage()
   184  	require.NoError(t, err1)
   185  
   186  	count := 10000
   187  	seqNum := uint64(1)
   188  	kvList := testMakeSortedKV(count, seqNum, 10)
   189  	seqNum += uint64(count)
   190  	wr := bp.GetPageWriter(pn, nil)
   191  	for i := 0; i < count; i++ {
   192  		require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value))
   193  	}
   194  	require.NoError(t, wr.FlushFinish())
   195  
   196  	p := bp.GetPage(pn)
   197  	wg := sync.WaitGroup{}
   198  	closeCh := make(chan struct{})
   199  	wg.Add(100)
   200  	for i := 0; i < 100; i++ {
   201  		if i%2 == 0 {
   202  			go func() {
   203  				defer wg.Done()
   204  				for {
   205  					select {
   206  					case <-closeCh:
   207  						return
   208  					default:
   209  						ri := rand.Intn(count)
   210  						uk := kvList[ri].Key.UserKey
   211  						v, vexist, vcloser, kind := p.get(uk, hash.Crc32(uk))
   212  						require.Equal(t, internalKeyKindSet, kind)
   213  						require.Equal(t, true, vexist)
   214  						require.Equal(t, kvList[ri].Value, v)
   215  						vcloser()
   216  					}
   217  				}
   218  			}()
   219  		} else {
   220  			go func() {
   221  				defer wg.Done()
   222  				for {
   223  					select {
   224  					case <-closeCh:
   225  						return
   226  					default:
   227  						iter := p.newIter(nil)
   228  						pos := rand.Intn(count - 20)
   229  						uk := kvList[pos].Key.UserKey
   230  						j := 0
   231  						for ik, iv := iter.SeekGE(uk); ik != nil; ik, iv = iter.Next() {
   232  							require.Equal(t, kvList[pos].Key, ik)
   233  							require.Equal(t, kvList[pos].Value, iv)
   234  							if j == 10 {
   235  								break
   236  							}
   237  							j++
   238  							pos++
   239  						}
   240  						require.NoError(t, iter.Close())
   241  					}
   242  				}
   243  			}()
   244  		}
   245  
   246  	}
   247  
   248  	time.Sleep(2 * time.Second)
   249  	wr = bp.GetPageWriter(pn, nil)
   250  	kvList1 := sortedkv.MakeSortedKVList(count, count+10, seqNum, 10)
   251  	for i := 0; i < 10; i++ {
   252  		require.NoError(t, wr.Set(*kvList1[i].Key, kvList1[i].Value))
   253  	}
   254  
   255  	wr.p.mu.stMutable.grow(consts.BitpageInitMmapSize + 1)
   256  	require.NoError(t, wr.FlushFinish())
   257  	require.Equal(t, consts.BitpageInitMmapSize*2, wr.p.mu.stMutable.tbl.Capacity())
   258  
   259  	close(closeCh)
   260  	wg.Wait()
   261  
   262  	testCloseBitpage(t, bp)
   263  }
   264  
   265  func TestBitpage_OpenPages(t *testing.T) {
   266  	defer os.RemoveAll(testDir)
   267  	os.RemoveAll(testDir)
   268  
   269  	var pageNums []PageNum
   270  	count := 1000
   271  	pagesCnt := 10
   272  	stCnt := 5
   273  	seqNum := uint64(1)
   274  	num := count * stCnt
   275  	kvList := testMakeSortedKV(num, seqNum, 10)
   276  	seqNum += uint64(num)
   277  
   278  	writePage := func(b *Bitpage) {
   279  		for i := 0; i < pagesCnt; i++ {
   280  			pn, err1 := b.NewPage()
   281  			require.NoError(t, err1)
   282  			pageNums = append(pageNums, pn)
   283  			wr := b.GetPageWriter(pn, nil)
   284  			for j := 0; j < stCnt; j++ {
   285  				start := j * count
   286  				end := start + count
   287  				for index := start; index < end; index++ {
   288  					require.NoError(t, wr.Set(*kvList[index].Key, kvList[index].Value))
   289  				}
   290  				wr.FlushFinish()
   291  				require.NoError(t, wr.p.makeMutableForWrite(false))
   292  			}
   293  		}
   294  	}
   295  
   296  	readPage := func(b *Bitpage, pn PageNum) {
   297  		p := b.GetPage(pn)
   298  		for i := 0; i < num; i++ {
   299  			key := kvList[i].Key.UserKey
   300  			v, vexist, vcloser, kind := p.get(key, hash.Crc32(key))
   301  			require.Equal(t, true, vexist)
   302  			require.Equal(t, kvList[i].Value, v)
   303  			require.Equal(t, internalKeyKindSet, kind)
   304  			vcloser()
   305  		}
   306  	}
   307  
   308  	bp, err := testOpenBitpage(true)
   309  	require.NoError(t, err)
   310  	writePage(bp)
   311  	testCloseBitpage(t, bp)
   312  
   313  	bp1, err1 := testOpenBitpage(true)
   314  	require.NoError(t, err1)
   315  	for _, pn := range pageNums {
   316  		readPage(bp1, pn)
   317  	}
   318  	writePage(bp1)
   319  	testCloseBitpage(t, bp1)
   320  
   321  	bp2, err2 := testOpenBitpage(true)
   322  	require.NoError(t, err2)
   323  	for _, pn := range pageNums {
   324  		readPage(bp2, pn)
   325  	}
   326  	testCloseBitpage(t, bp2)
   327  }
   328  
   329  func TestBitpage_Iter_SameKey(t *testing.T) {
   330  	defer os.RemoveAll(testDir)
   331  	os.RemoveAll(testDir)
   332  
   333  	bp, err := testOpenBitpage(true)
   334  	require.NoError(t, err)
   335  	pn, err1 := bp.NewPage()
   336  	require.NoError(t, err1)
   337  
   338  	wr := bp.GetPageWriter(pn, nil)
   339  	seqNum := uint64(1)
   340  	count := 100
   341  	kvList := testMakeSortedKV(count, seqNum, 10)
   342  	seqNum += uint64(count)
   343  
   344  	for j := 0; j < 100; j++ {
   345  		for i := 0; i < count; i++ {
   346  			kvList[i].Key.SetSeqNum(seqNum)
   347  			seqNum++
   348  			kvList[i].Value = utils.FuncRandBytes(10)
   349  			require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value))
   350  		}
   351  		require.NoError(t, wr.FlushFinish())
   352  	}
   353  
   354  	checkKV := func(i int, ikey *internalKey, ival []byte) {
   355  		require.Equal(t, kvList[i].Key.UserKey, ikey.UserKey)
   356  		require.Equal(t, kvList[i].Value, ival)
   357  		require.Equal(t, internalKeyKindSet, ikey.Kind())
   358  	}
   359  
   360  	rangeFunc := func(p *page) {
   361  		iter := p.newIter(nil)
   362  		i := 0
   363  		for ik, iv := iter.First(); ik != nil; ik, iv = iter.Next() {
   364  			checkKV(i, ik, iv)
   365  			i++
   366  		}
   367  		require.NoError(t, iter.Close())
   368  
   369  		iter = p.newIter(nil)
   370  		i = len(kvList) - 1
   371  		for ik, iv := iter.Last(); ik != nil; ik, iv = iter.Prev() {
   372  			checkKV(i, ik, iv)
   373  			i--
   374  		}
   375  		require.NoError(t, iter.Close())
   376  	}
   377  
   378  	seekFunc := func(p *page) {
   379  		iter := p.newIter(nil)
   380  		for i := 0; i < count; i++ {
   381  			ik, iv := iter.SeekGE(kvList[i].Key.UserKey)
   382  			checkKV(i, ik, iv)
   383  		}
   384  		require.NoError(t, iter.Close())
   385  	}
   386  
   387  	pg := bp.GetPage(pn)
   388  	rangeFunc(pg)
   389  	seekFunc(pg)
   390  	testCloseBitpage(t, bp)
   391  
   392  	bp2, err2 := testOpenBitpage(true)
   393  	require.NoError(t, err2)
   394  	pg2 := bp2.GetPage(pn)
   395  	rangeFunc(pg2)
   396  	seekFunc(pg2)
   397  	testCloseBitpage(t, bp2)
   398  }
   399  
   400  func TestBitpage_Iter_StGet(t *testing.T) {
   401  	defer os.RemoveAll(testDir)
   402  	os.RemoveAll(testDir)
   403  
   404  	bp, err := testOpenBitpage(true)
   405  	require.NoError(t, err)
   406  	pn, err1 := bp.NewPage()
   407  	require.NoError(t, err1)
   408  	wr := bp.GetPageWriter(pn, nil)
   409  
   410  	seqNum := uint64(1)
   411  	count := 100
   412  	kvList := testMakeSortedKV(count, seqNum, 10)
   413  	seqNum += uint64(count)
   414  	key := kvList[0].Key.UserKey
   415  	for i := 0; i < count; i++ {
   416  		require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value))
   417  	}
   418  	require.NoError(t, wr.FlushFinish())
   419  
   420  	seekFunc := func(p *page) {
   421  		iter := p.newIter(nil)
   422  		ik, iv := iter.SeekGE(key)
   423  		require.Equal(t, kvList[0].Key, ik)
   424  		require.Equal(t, kvList[0].Value, iv)
   425  		ik, iv = iter.SeekLT(key)
   426  		require.Equal(t, nilInternalKey, ik)
   427  		require.NoError(t, iter.Close())
   428  	}
   429  
   430  	pg := bp.GetPage(pn)
   431  	seekFunc(pg)
   432  	testCloseBitpage(t, bp)
   433  
   434  	bp2, err2 := testOpenBitpage(true)
   435  	require.NoError(t, err2)
   436  	pg2 := bp2.GetPage(pn)
   437  	seekFunc(pg2)
   438  	testCloseBitpage(t, bp2)
   439  }
   440  
   441  func testcase(caseFunc func(int, []bool)) {
   442  	for i, params := range testParams {
   443  		fmt.Printf("testcase params:%v\n", params)
   444  		caseFunc(i, params)
   445  	}
   446  }
   447  
   448  func TestBitpageWriterDelete(t *testing.T) {
   449  	testcase(func(index int, params []bool) {
   450  		dir := testDir
   451  		defer os.RemoveAll(dir)
   452  		os.RemoveAll(dir)
   453  		bp, err := testOpenBitpage2(dir, params[0], params[1], params[2])
   454  		require.NoError(t, err)
   455  		count := 1000
   456  		seqNum := uint64(1)
   457  		kvList := testMakeSortedKV(count, seqNum, 10)
   458  		seqNum += uint64(count)
   459  		pn, err1 := bp.NewPage()
   460  		require.NoError(t, err1)
   461  		wr := bp.GetPageWriter(pn, nil)
   462  		writeKV := func(pos int) {
   463  			require.NoError(t, wr.Set(*kvList[pos].Key, kvList[pos].Value))
   464  		}
   465  
   466  		for i := 0; i < count; i++ {
   467  			writeKV(i)
   468  		}
   469  		require.NoError(t, wr.FlushFinish())
   470  
   471  		p := bp.GetPage(pn)
   472  		for i := 0; i < count; i++ {
   473  			key := kvList[i].Key.UserKey
   474  			v, vexist, vcloser, kind := p.get(key, hash.Crc32(key))
   475  			require.Equal(t, true, vexist)
   476  			require.Equal(t, kvList[i].Value, v)
   477  			require.Equal(t, internalKeyKindSet, kind)
   478  			vcloser()
   479  		}
   480  
   481  		require.NoError(t, p.flush(nil, ""))
   482  
   483  		for i := 10; i < 20; i++ {
   484  			kvList[i].Key.SetKind(internalKeyKindDelete)
   485  			kvList[i].Key.SetSeqNum(seqNum)
   486  			seqNum++
   487  			writeKV(i)
   488  		}
   489  		require.NoError(t, wr.FlushFinish())
   490  
   491  		for i := 0; i < count; i++ {
   492  			key := kvList[i].Key.UserKey
   493  			v, vexist, vcloser, kind := p.get(key, hash.Crc32(key))
   494  			if i >= 10 && i < 20 {
   495  				require.Equal(t, true, vcloser == nil)
   496  				require.Equal(t, false, vexist)
   497  				require.Equal(t, internalKeyKindDelete, kind)
   498  			} else {
   499  				require.Equal(t, true, vexist)
   500  				require.Equal(t, kvList[i].Value, v)
   501  				require.Equal(t, internalKeyKindSet, kind)
   502  				vcloser()
   503  			}
   504  		}
   505  
   506  		testCloseBitpage(t, bp)
   507  	})
   508  }
   509  
   510  func TestBitpageIter(t *testing.T) {
   511  	testcase(func(index int, params []bool) {
   512  		dir := testDir
   513  		defer os.RemoveAll(dir)
   514  		os.RemoveAll(dir)
   515  		bp, err := testOpenBitpage2(dir, params[0], params[1], params[2])
   516  		require.NoError(t, err)
   517  		pn, err1 := bp.NewPage()
   518  		require.NoError(t, err1)
   519  		wr := bp.GetPageWriter(pn, nil)
   520  		seqNum := uint64(1)
   521  		count := 100
   522  		kvList := testMakeSortedKV(count, seqNum, 10)
   523  		seqNum += uint64(count)
   524  
   525  		for i := 0; i < count; i++ {
   526  			require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value))
   527  		}
   528  		require.NoError(t, wr.FlushFinish())
   529  
   530  		pg := bp.GetPage(pn)
   531  		require.NoError(t, pg.flush(nil, ""))
   532  		for i := 20; i < 30; i++ {
   533  			kvList[i].Key.SetKind(internalKeyKindDelete)
   534  			kvList[i].Key.SetSeqNum(seqNum)
   535  			kvList[i].Value = nil
   536  			seqNum++
   537  			require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value))
   538  		}
   539  		require.NoError(t, wr.FlushFinish())
   540  
   541  		for i := 80; i < count; i++ {
   542  			kvList[i].Key.SetSeqNum(seqNum)
   543  			kvList[i].Value = utils.FuncRandBytes(10)
   544  			seqNum++
   545  			require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value))
   546  		}
   547  		require.NoError(t, wr.FlushFinish())
   548  
   549  		checkKV := func(i int, ikey *internalKey, ival []byte) {
   550  			if i < 0 {
   551  				require.Equal(t, nilInternalKey, ikey)
   552  				require.Equal(t, 0, len(ival))
   553  			} else {
   554  				require.Equal(t, kvList[i].Key.UserKey, ikey.UserKey)
   555  				if i >= 20 && i < 30 {
   556  					require.Equal(t, 0, len(ival))
   557  					require.Equal(t, internalKeyKindDelete, ikey.Kind())
   558  				} else {
   559  					require.Equal(t, kvList[i].Value, ival)
   560  					require.Equal(t, internalKeyKindSet, ikey.Kind())
   561  				}
   562  			}
   563  		}
   564  
   565  		rangeFunc := func(p *page) {
   566  			iter := p.newIter(nil)
   567  			setCnt := 0
   568  			delCnt := 0
   569  			index := 0
   570  			for ik, iv := iter.First(); ik != nil; ik, iv = iter.Next() {
   571  				checkKV(index, ik, iv)
   572  				if ik.Kind() == internalKeyKindSet {
   573  					setCnt++
   574  				} else if ik.Kind() == internalKeyKindDelete {
   575  					delCnt++
   576  				}
   577  				index++
   578  			}
   579  			require.Equal(t, count-10, setCnt)
   580  			require.Equal(t, 10, delCnt)
   581  
   582  			setCnt = 0
   583  			delCnt = 0
   584  			index = 99
   585  			for ik, iv := iter.Last(); ik != nil; ik, iv = iter.Prev() {
   586  				checkKV(index, ik, iv)
   587  				if ik.Kind() == internalKeyKindSet {
   588  					setCnt++
   589  				} else if ik.Kind() == internalKeyKindDelete {
   590  					delCnt++
   591  				}
   592  				index--
   593  			}
   594  			require.Equal(t, count-10, setCnt)
   595  			require.Equal(t, 10, delCnt)
   596  			require.NoError(t, iter.Close())
   597  		}
   598  
   599  		seekFunc := func(p *page) {
   600  			iter := p.newIter(nil)
   601  			for i := 0; i < count; i++ {
   602  				key := kvList[i].Key.UserKey
   603  				ik, iv := iter.SeekGE(key)
   604  				checkKV(i, ik, iv)
   605  			}
   606  			require.NoError(t, iter.Close())
   607  		}
   608  
   609  		seekFunc1 := func(p *page) {
   610  			iter := p.newIter(nil)
   611  
   612  			ik, iv := iter.Prev()
   613  			checkKV(99, ik, iv)
   614  
   615  			ik, iv = iter.First()
   616  			checkKV(0, ik, iv)
   617  			ik, iv = iter.Next()
   618  			checkKV(1, ik, iv)
   619  			ik, iv = iter.Prev()
   620  			checkKV(0, ik, iv)
   621  			ik, iv = iter.Last()
   622  			checkKV(99, ik, iv)
   623  			ik, iv = iter.Prev()
   624  			checkKV(98, ik, iv)
   625  
   626  			ik, iv = iter.SeekGE(kvList[15].Key.UserKey)
   627  			checkKV(15, ik, iv)
   628  			ik, iv = iter.SeekGE(kvList[99].Key.UserKey)
   629  			checkKV(99, ik, iv)
   630  
   631  			ik, iv = iter.SeekGE(sortedkv.MakeSortedKey(990))
   632  			checkKV(-1, ik, iv)
   633  			ik, iv = iter.SeekGE(sortedkv.MakeSortedKey(-1))
   634  			checkKV(0, ik, iv)
   635  
   636  			ik, iv = iter.SeekLT(kvList[35].Key.UserKey)
   637  			checkKV(34, ik, iv)
   638  			ik, iv = iter.Prev()
   639  			checkKV(33, ik, iv)
   640  
   641  			ik, iv = iter.SeekGE(kvList[20].Key.UserKey)
   642  			checkKV(20, ik, iv)
   643  			ik, iv = iter.SeekGE(kvList[29].Key.UserKey)
   644  			checkKV(29, ik, iv)
   645  			ik, iv = iter.Next()
   646  			checkKV(30, ik, iv)
   647  
   648  			ik, iv = iter.SeekLT(kvList[30].Key.UserKey)
   649  			checkKV(29, ik, iv)
   650  			ik, iv = iter.Prev()
   651  			checkKV(28, ik, iv)
   652  
   653  			ik, iv = iter.SeekLT(kvList[21].Key.UserKey)
   654  			checkKV(20, ik, iv)
   655  			ik, iv = iter.SeekLT(kvList[20].Key.UserKey)
   656  			checkKV(19, ik, iv)
   657  			ik, iv = iter.Prev()
   658  			checkKV(18, ik, iv)
   659  
   660  			ik, iv = iter.SeekLT(sortedkv.MakeSortedKey(990))
   661  			checkKV(99, ik, iv)
   662  			ik, iv = iter.SeekLT(sortedkv.MakeSortedKey(-1))
   663  			checkKV(-1, ik, iv)
   664  
   665  			require.NoError(t, iter.Close())
   666  		}
   667  
   668  		rangeFunc(pg)
   669  		seekFunc(pg)
   670  		seekFunc1(pg)
   671  		testCloseBitpage(t, bp)
   672  
   673  		bp2, err2 := testOpenBitpage2(dir, params[0], params[1], params[2])
   674  		require.NoError(t, err2)
   675  		pg2 := bp2.GetPage(pn)
   676  		rangeFunc(pg2)
   677  		seekFunc(pg2)
   678  		seekFunc1(pg2)
   679  		testCloseBitpage(t, bp2)
   680  	})
   681  }
   682  
   683  func TestBitpageIterRange(t *testing.T) {
   684  	testcase(func(index int, params []bool) {
   685  		dir := testDir
   686  		defer os.RemoveAll(dir)
   687  		os.RemoveAll(dir)
   688  		bp, err := testOpenBitpage2(dir, params[0], params[1], params[2])
   689  		require.NoError(t, err)
   690  		pn, err1 := bp.NewPage()
   691  		require.NoError(t, err1)
   692  		wr := bp.GetPageWriter(pn, nil)
   693  		seqNum := uint64(1)
   694  		count := 10000
   695  		kvList := testMakeSortedKV(count+1, seqNum, 100)
   696  		seqNum += uint64(count)
   697  
   698  		rangeIter := func(p *page) {
   699  			iter := p.newIter(nil)
   700  			i := 0
   701  			for ik, iv := iter.First(); ik != nil; ik, iv = iter.Next() {
   702  				require.Equal(t, kvList[i].Key.UserKey, ik.UserKey)
   703  				require.Equal(t, kvList[i].Value, iv)
   704  				i++
   705  			}
   706  			require.Equal(t, i, count)
   707  			require.NoError(t, iter.Close())
   708  
   709  			iter = p.newIter(nil)
   710  			for i = 0; i < count; i++ {
   711  				ik, iv := iter.SeekGE(kvList[i].Key.UserKey)
   712  				require.Equal(t, kvList[i].Key.UserKey, ik.UserKey)
   713  				require.Equal(t, kvList[i].Value, iv)
   714  			}
   715  			require.NoError(t, iter.Close())
   716  		}
   717  
   718  		rangeReverseIter := func(p *page) {
   719  			iter := p.newIter(nil)
   720  			i := count - 1
   721  			for ik, iv := iter.Last(); ik != nil; ik, iv = iter.Prev() {
   722  				require.Equal(t, kvList[i].Key.UserKey, ik.UserKey)
   723  				require.Equal(t, kvList[i].Value, iv)
   724  				i--
   725  			}
   726  			require.Equal(t, -1, i)
   727  			require.NoError(t, iter.Close())
   728  
   729  			iter = p.newIter(nil)
   730  			for i = count; i >= 0; i-- {
   731  				ik, iv := iter.SeekLT(kvList[i].Key.UserKey)
   732  				if i == 0 {
   733  					require.Equal(t, nilInternalKey, ik)
   734  					require.Equal(t, []byte(nil), iv)
   735  				} else {
   736  					require.Equal(t, kvList[i-1].Key.UserKey, ik.UserKey)
   737  					require.Equal(t, kvList[i-1].Value, iv)
   738  				}
   739  			}
   740  			require.NoError(t, iter.Close())
   741  		}
   742  
   743  		for i := 0; i < count; i++ {
   744  			require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value))
   745  		}
   746  		require.NoError(t, wr.FlushFinish())
   747  
   748  		pg := bp.GetPage(pn)
   749  		rangeIter(pg)
   750  		rangeReverseIter(pg)
   751  		require.NoError(t, pg.flush(nil, ""))
   752  		rangeIter(pg)
   753  		rangeReverseIter(pg)
   754  		testCloseBitpage(t, bp)
   755  
   756  		bp2, err2 := testOpenBitpage2(dir, params[0], params[1], params[2])
   757  		require.NoError(t, err2)
   758  		pg2 := bp2.GetPage(pn)
   759  		rangeIter(pg2)
   760  		rangeReverseIter(pg2)
   761  		testCloseBitpage(t, bp2)
   762  	})
   763  }
   764  
   765  func TestBitpageCheckpoint(t *testing.T) {
   766  	testcase(func(index int, params []bool) {
   767  		defer os.RemoveAll(testDir)
   768  		os.RemoveAll(testDir)
   769  		openBitpage := func(dir string) *Bitpage {
   770  			b, err := testOpenBitpage2(dir, params[0], params[1], params[2])
   771  			require.NoError(t, err)
   772  			return b
   773  		}
   774  		bp := openBitpage(testDir)
   775  		pn, err := bp.NewPage()
   776  		require.NoError(t, err)
   777  		pg := bp.GetPage(pn)
   778  		dstDir := fmt.Sprintf("%s_ck", testDir)
   779  		os.RemoveAll(dstDir)
   780  		defer os.RemoveAll(dstDir)
   781  		require.NoError(t, bp.Checkpoint(bp.opts.FS, dstDir))
   782  		bp1 := openBitpage(dstDir)
   783  		pg1 := bp1.GetPage(pn)
   784  		require.Equal(t, 1, len(pg.mu.stQueue))
   785  		require.Equal(t, 1, len(pg1.mu.stQueue))
   786  		require.Equal(t, true, pg.mu.arrtable == nil)
   787  		require.Equal(t, true, pg1.mu.arrtable == nil)
   788  		require.NoError(t, bp1.Close())
   789  		require.NoError(t, os.RemoveAll(dstDir))
   790  
   791  		wr := bp.GetPageWriter(pn, nil)
   792  		seqNum := uint64(1)
   793  		count := 2000
   794  		kvList := testMakeSortedKV(count, seqNum, 10)
   795  		seqNum += uint64(count)
   796  
   797  		for i := 0; i < 1000; i++ {
   798  			require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value))
   799  		}
   800  		require.NoError(t, wr.FlushFinish())
   801  		require.NoError(t, pg.flush(nil, ""))
   802  		for i := 1000; i < 2000; i++ {
   803  			require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value))
   804  		}
   805  		require.NoError(t, wr.FlushFinish())
   806  
   807  		for i := 0; i < 3; i++ {
   808  			fmt.Println("checkpoint", i)
   809  			dstDir = fmt.Sprintf("%s_ck_%d", testDir, i)
   810  			require.NoError(t, os.RemoveAll(dstDir))
   811  			require.NoError(t, bp.Checkpoint(bp.opts.FS, dstDir))
   812  			bp1 = openBitpage(dstDir)
   813  			pg1 = bp1.GetPage(pn)
   814  			require.Equal(t, 2, len(pg.mu.stQueue))
   815  			require.Equal(t, 1, len(pg1.mu.stQueue))
   816  			require.Equal(t, true, pg.mu.arrtable != nil)
   817  			require.Equal(t, true, pg1.mu.arrtable != nil)
   818  			for j := 0; j < 2000; j++ {
   819  				key := kvList[j].Key.UserKey
   820  				v, vexist, vcloser, kind := pg1.get(key, hash.Crc32(key))
   821  				require.Equal(t, true, vexist)
   822  				require.Equal(t, kvList[j].Value, v)
   823  				require.Equal(t, internalKeyKindSet, kind)
   824  				vcloser()
   825  				v, vexist, vcloser, kind = pg.get(key, hash.Crc32(key))
   826  				require.Equal(t, true, vexist)
   827  				require.Equal(t, kvList[j].Value, v)
   828  				require.Equal(t, internalKeyKindSet, kind)
   829  				vcloser()
   830  			}
   831  			testCloseBitpage(t, bp1)
   832  			require.NoError(t, os.RemoveAll(dstDir))
   833  		}
   834  
   835  		testCloseBitpage(t, bp)
   836  	})
   837  }
   838  
   839  func TestBitpageCheckpoint1(t *testing.T) {
   840  	testcase(func(index int, params []bool) {
   841  		defer os.RemoveAll(testDir)
   842  		os.RemoveAll(testDir)
   843  		openBitpage := func(dir string) *Bitpage {
   844  			b, err := testOpenBitpage2(dir, params[0], params[1], params[2])
   845  			require.NoError(t, err)
   846  			return b
   847  		}
   848  		bp := openBitpage(testDir)
   849  		pn, err := bp.NewPage()
   850  		require.NoError(t, err)
   851  		wr := bp.GetPageWriter(pn, nil)
   852  		seqNum := uint64(1)
   853  		count := 20000
   854  		kvList := testMakeSortedKV(count, seqNum, 100)
   855  		seqNum += uint64(count)
   856  
   857  		for i := 0; i < count/2; i++ {
   858  			require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value))
   859  		}
   860  		require.NoError(t, wr.FlushFinish())
   861  
   862  		pg := bp.GetPage(pn)
   863  		require.NoError(t, pg.flush(nil, ""))
   864  
   865  		for i := count / 2; i < count; i++ {
   866  			require.NoError(t, wr.Set(*kvList[i].Key, kvList[i].Value))
   867  		}
   868  		require.NoError(t, wr.FlushFinish())
   869  
   870  		sps, err2 := bp.PageSplitStart(pn, "test")
   871  		require.NoError(t, err2)
   872  		bp.PageSplitEnd(pn, sps, nil)
   873  		fmt.Println("page split ok")
   874  
   875  		dstDir := fmt.Sprintf("%s_ck", testDir)
   876  		os.RemoveAll(dstDir)
   877  		defer os.RemoveAll(dstDir)
   878  		require.NoError(t, bp.Checkpoint(bp.opts.FS, dstDir))
   879  		require.Equal(t, consts.BitpageSplitNum+1, bp.GetPageCount())
   880  		require.Equal(t, true, bp.PageSplitted2(pn))
   881  		require.Equal(t, true, pg.mu.arrtable != nil)
   882  		bp1 := openBitpage(dstDir)
   883  		pg1 := bp1.GetPage(pn)
   884  		require.Equal(t, true, pg1 == nil)
   885  		for i := range sps {
   886  			spn := bp1.GetPage(sps[i].Pn)
   887  			require.Equal(t, true, spn != nil)
   888  			require.Equal(t, 1, len(spn.mu.stQueue))
   889  			require.Equal(t, true, spn.mu.arrtable != nil)
   890  		}
   891  
   892  		for j := 0; j < count; j++ {
   893  			key := kvList[j].Key.UserKey
   894  			v, vexist, vcloser, kind := pg.get(key, hash.Crc32(key))
   895  			require.Equal(t, true, vexist)
   896  			require.Equal(t, kvList[j].Value, v)
   897  			require.Equal(t, internalKeyKindSet, kind)
   898  			vcloser()
   899  
   900  			find := false
   901  			for i := range sps {
   902  				if bytes.Compare(key, sps[i].Sentinel) <= 0 {
   903  					v, vexist, vcloser, kind = bp1.Get(sps[i].Pn, key, hash.Crc32(key))
   904  					require.Equal(t, true, vexist)
   905  					require.Equal(t, kvList[j].Value, v)
   906  					require.Equal(t, internalKeyKindSet, kind)
   907  					vcloser()
   908  					find = true
   909  					break
   910  				}
   911  			}
   912  			require.Equal(t, true, find)
   913  		}
   914  
   915  		testCloseBitpage(t, bp)
   916  	})
   917  }