github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitree/bithash_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 bitree
    16  
    17  import (
    18  	"fmt"
    19  	"os"
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/stretchr/testify/require"
    24  	"github.com/zuoyebang/bitalosdb/bithash"
    25  	"github.com/zuoyebang/bitalosdb/internal/base"
    26  	"github.com/zuoyebang/bitalosdb/internal/hash"
    27  )
    28  
    29  func TestBithash_Compact(t *testing.T) {
    30  	defer os.RemoveAll(testDir)
    31  	os.RemoveAll(testDir)
    32  
    33  	testBithashSize = 1 << 20
    34  	btree, _ := testOpenBitree()
    35  
    36  	num := 2000
    37  	seqNum := uint64(0)
    38  	kvList := testMakeSortedKV(num, seqNum, 2048)
    39  	seqNum += uint64(num)
    40  
    41  	writeFunc := func() {
    42  		bw, err := btree.NewBitreeWriter()
    43  		require.NoError(t, err)
    44  		for i := 0; i < num; i++ {
    45  			pn, sentinel, closer := btree.FindKeyPageNum(kvList[i].Key.UserKey)
    46  			closer()
    47  			require.NotEqual(t, nilPageNum, pn)
    48  			require.NoError(t, bw.set(*kvList[i].Key, kvList[i].Value, pn, sentinel))
    49  		}
    50  		require.NoError(t, bw.Finish())
    51  		time.Sleep(1 * time.Second)
    52  	}
    53  
    54  	deleteFunc := func(n int) {
    55  		bw, err := btree.NewBitreeWriter()
    56  		require.NoError(t, err)
    57  		for i := 0; i < num; i++ {
    58  			if n > 0 && i%n == 0 {
    59  				continue
    60  			}
    61  			pn, sentinel, closer := btree.FindKeyPageNum(kvList[i].Key.UserKey)
    62  			closer()
    63  			require.NotEqual(t, nilPageNum, pn)
    64  			kvList[i].Key.SetKind(base.InternalKeyKindDelete)
    65  			kvList[i].Key.SetSeqNum(seqNum)
    66  			kvList[i].Value = []byte(nil)
    67  			require.NoError(t, bw.set(*kvList[i].Key, kvList[i].Value, pn, sentinel))
    68  			seqNum++
    69  		}
    70  		require.NoError(t, bw.Finish())
    71  		time.Sleep(1 * time.Second)
    72  	}
    73  
    74  	readFun := func() int {
    75  		btree, _ = testOpenBitree()
    76  		findNum := 0
    77  		for i := 0; i < num; i++ {
    78  			key := kvList[i].Key.UserKey
    79  			value, vexist, vpool := btree.Get(key, hash.Crc32(key))
    80  			if !vexist {
    81  				continue
    82  			}
    83  			require.Equal(t, kvList[i].Value, value)
    84  			vpool()
    85  			findNum++
    86  		}
    87  		return findNum
    88  	}
    89  
    90  	writeFunc()
    91  	deleteFunc(2)
    92  
    93  	btree.CompactBithash(0.05)
    94  	require.NoError(t, testBitreeClose(btree))
    95  
    96  	readNum := readFun()
    97  	require.Equal(t, int(1000), readNum)
    98  	require.Equal(t, bithash.FileNum(4), btree.bhash.GetFileNumMap(bithash.FileNum(4)))
    99  	require.NoError(t, testBitreeClose(btree))
   100  
   101  	btree, _ = testOpenBitree()
   102  	deleteFunc(3)
   103  	btree.CompactBithash(0.05)
   104  	require.NoError(t, testBitreeClose(btree))
   105  
   106  	readNum = readFun()
   107  	require.Equal(t, int(334), readNum)
   108  	require.NoError(t, testBitreeClose(btree))
   109  
   110  	btree, _ = testOpenBitree()
   111  	deleteFunc(0)
   112  	btree.CompactBithash(0.05)
   113  	require.NoError(t, testBitreeClose(btree))
   114  
   115  	readNum = readFun()
   116  	require.Equal(t, int(0), readNum)
   117  	require.NoError(t, testBitreeClose(btree))
   118  }
   119  
   120  func TestBithash_Compact2(t *testing.T) {
   121  	defer os.RemoveAll(testDir)
   122  	os.RemoveAll(testDir)
   123  
   124  	testBithashSize = 10 << 20
   125  	btree, _ := testOpenBitree()
   126  
   127  	writeNum := 0
   128  	deleteNum := 0
   129  	curNum := 0
   130  	num := 30000
   131  	seqNum := uint64(0)
   132  	kvList := testMakeSortedKV(num, seqNum, 2048)
   133  	seqNum += uint64(num)
   134  
   135  	writeFunc := func() {
   136  		bw, err := btree.NewBitreeWriter()
   137  		require.NoError(t, err)
   138  		for writeNum < num {
   139  			item := kvList[writeNum]
   140  			pn, sentinel, closer := btree.FindKeyPageNum(item.Key.UserKey)
   141  			closer()
   142  			require.NotEqual(t, nilPageNum, pn)
   143  			require.NoError(t, bw.set(*item.Key, item.Value, pn, sentinel))
   144  			writeNum++
   145  			if writeNum%10000 == 0 {
   146  				break
   147  			}
   148  		}
   149  		require.NoError(t, bw.Finish())
   150  		time.Sleep(1 * time.Second)
   151  	}
   152  
   153  	deleteFunc := func() {
   154  		bw, err := btree.NewBitreeWriter()
   155  		require.NoError(t, err)
   156  		for curNum < writeNum {
   157  			item := kvList[curNum]
   158  			pn, sentinel, closer := btree.FindKeyPageNum(item.Key.UserKey)
   159  			closer()
   160  			require.NotEqual(t, nilPageNum, pn)
   161  			item.Key.SetKind(base.InternalKeyKindDelete)
   162  			item.Key.SetSeqNum(seqNum)
   163  			item.Value = []byte(nil)
   164  			require.NoError(t, bw.set(*item.Key, item.Value, pn, sentinel))
   165  			seqNum++
   166  			deleteNum++
   167  			curNum++
   168  			if curNum > writeNum-100 {
   169  				break
   170  			}
   171  		}
   172  		curNum = writeNum
   173  		require.NoError(t, bw.Finish())
   174  		time.Sleep(1 * time.Second)
   175  	}
   176  
   177  	readFun := func() int {
   178  		btree, _ = testOpenBitree()
   179  		findNum := 0
   180  		for i := 0; i < num; i++ {
   181  			key := kvList[i].Key.UserKey
   182  			value, vexist, vpool := btree.Get(key, hash.Crc32(key))
   183  			if !vexist {
   184  				continue
   185  			}
   186  			require.Equal(t, kvList[i].Value, value)
   187  			vpool()
   188  			findNum++
   189  		}
   190  		return findNum
   191  	}
   192  
   193  	for writeNum < num {
   194  		writeFunc()
   195  		deleteFunc()
   196  		btree.CompactBithash(0.05)
   197  	}
   198  
   199  	require.NoError(t, testBitreeClose(btree))
   200  	readNum := readFun()
   201  	require.Equal(t, num-deleteNum, readNum)
   202  	require.NoError(t, testBitreeClose(btree))
   203  }
   204  
   205  func TestBithash_Compact3(t *testing.T) {
   206  	defer os.RemoveAll(testDir)
   207  	os.RemoveAll(testDir)
   208  
   209  	testBithashSize = 1 << 20
   210  	btree, _ := testOpenBitree()
   211  
   212  	num := 10000
   213  	seqNum := uint64(0)
   214  	kvList := testMakeSortedKV(num, seqNum, 2048)
   215  	seqNum += uint64(num)
   216  	writeNum := 0
   217  	deleteNum := 0
   218  
   219  	writeFunc := func() {
   220  		bw, err := btree.NewBitreeWriter()
   221  		require.NoError(t, err)
   222  		for writeNum < num {
   223  			item := kvList[writeNum]
   224  			pn, sentinel, closer := btree.FindKeyPageNum(item.Key.UserKey)
   225  			closer()
   226  			require.NotEqual(t, nilPageNum, pn)
   227  			require.NoError(t, bw.set(*item.Key, item.Value, pn, sentinel))
   228  			writeNum++
   229  		}
   230  		require.NoError(t, bw.Finish())
   231  		time.Sleep(1 * time.Second)
   232  	}
   233  
   234  	deleteFunc := func() {
   235  		bw, err := btree.NewBitreeWriter()
   236  		require.NoError(t, err)
   237  		for i := 0; i < writeNum; i++ {
   238  			item := kvList[i]
   239  			if i > writeNum-100 {
   240  				break
   241  			}
   242  			pn, sentinel, closer := btree.FindKeyPageNum(item.Key.UserKey)
   243  			closer()
   244  			require.NotEqual(t, nilPageNum, pn)
   245  			item.Key.SetKind(base.InternalKeyKindDelete)
   246  			item.Key.SetSeqNum(seqNum)
   247  			item.Value = []byte(nil)
   248  			require.NoError(t, bw.set(*item.Key, item.Value, pn, sentinel))
   249  			deleteNum++
   250  			seqNum++
   251  		}
   252  		require.NoError(t, bw.Finish())
   253  		time.Sleep(1 * time.Second)
   254  	}
   255  
   256  	writeFunc()
   257  	deleteFunc()
   258  	btree.CompactBithash(0.05)
   259  	fmt.Println("db.bhash.Stats()", btree.bhash.Stats())
   260  	require.NoError(t, testBitreeClose(btree))
   261  
   262  	btree, _ = testOpenBitree()
   263  	readNum := 0
   264  	for i := 0; i < writeNum; i++ {
   265  		item := kvList[i]
   266  		key := item.Key.UserKey
   267  		value, vexist, vpool := btree.Get(key, hash.Crc32(key))
   268  		if i > writeNum-100 {
   269  			if !vexist {
   270  				t.Fatalf("key not find key=%s", item.Key.String())
   271  			}
   272  			require.Equal(t, item.Value, value)
   273  			vpool()
   274  			readNum++
   275  		} else if vexist {
   276  			t.Fatalf("delete key find key=%s", item.Key.String())
   277  		}
   278  	}
   279  	require.Equal(t, num-deleteNum, readNum)
   280  	require.NoError(t, testBitreeClose(btree))
   281  }