github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bithash/writer_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 bithash
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"strconv"
    21  	"strings"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/require"
    25  	"github.com/zuoyebang/bitalosdb/internal/base"
    26  	"github.com/zuoyebang/bitalosdb/internal/unsafe2"
    27  )
    28  
    29  func TestFixedWidthWrite(t *testing.T) {
    30  	f0, err := testMemFs.Create("filename")
    31  	if err != nil {
    32  		panic(err)
    33  	}
    34  	for _, indexBH := range []BlockHandle{{4, 6}, {18, 3}, {9999, 8888}, {19923892, 2378237}, {6, 7}, {2893824823, 239924829}, {88, 35}} {
    35  		buf2 := make([]byte, 20)
    36  		encodeBlockHandle(buf2, indexBH)
    37  		n, err := f0.Write(buf2)
    38  		if err != nil {
    39  			panic(err)
    40  		}
    41  		if n != 20 {
    42  			fmt.Println("no equal")
    43  		}
    44  	}
    45  	if err = f0.Close(); err != nil {
    46  		panic(err)
    47  	}
    48  
    49  	f1, err := testMemFs.Open("filename")
    50  	if err != nil {
    51  		panic(err)
    52  	}
    53  	off := 0
    54  	for i := 0; i < 7; i++ {
    55  		buff := make([]byte, 20)
    56  		_, err = f1.ReadAt(buff, int64(off))
    57  		if err != nil {
    58  			panic(err)
    59  		}
    60  		bbh := decodeBlockHandle(buff)
    61  		fmt.Printf("index:%d,blockhandle:%+v", i, bbh)
    62  		off += 20
    63  	}
    64  	if err = f1.Close(); err != nil {
    65  		panic(err)
    66  	}
    67  }
    68  
    69  func TestBlockFile(t *testing.T) {
    70  	f0, err := testMemFs.Create("filename")
    71  	if err != nil {
    72  		panic(err)
    73  	}
    74  	makeIkey := func(s string) InternalKey {
    75  		j := strings.Index(s, ":")
    76  		seq, err := strconv.Atoi(s[j+1:])
    77  		if err != nil {
    78  			panic(err)
    79  		}
    80  		return base.MakeInternalKey([]byte(s[:j]), uint64(seq), InternalKeyKindSet)
    81  	}
    82  	var block []byte
    83  	w := &blockWriter{}
    84  	for k, e := range strings.Split(strings.TrimSpace("a:1,b:2,c:3,d:4"), ",") {
    85  		w.add(makeIkey(e), []byte(fmt.Sprintf("hello"+strconv.Itoa(k+100))))
    86  	}
    87  	block = w.finish()
    88  	n, err := f0.Write(block)
    89  	if err != nil {
    90  		panic(err)
    91  	}
    92  	if err := f0.Close(); err != nil {
    93  		panic(err)
    94  	}
    95  	f1, err := testMemFs.Open("filename")
    96  	if err != nil {
    97  		panic(err)
    98  	}
    99  	buff := make([]byte, n)
   100  	_, err = f1.ReadAt(buff, 0)
   101  	if err != nil {
   102  		panic(err)
   103  	}
   104  	iter, err := newBlockIter(bytes.Compare, buff)
   105  	if err != nil {
   106  		panic(err)
   107  	}
   108  	fi, fv := iter.First()
   109  	fmt.Println("first:", fi, string(fv))
   110  	si, sv := iter.Next()
   111  	fmt.Println("second:", si, string(sv))
   112  }
   113  
   114  func TestWriteReadBlock(t *testing.T) {
   115  	makeIkey := func(s string) InternalKey {
   116  		j := strings.Index(s, ":")
   117  		seq, err := strconv.Atoi(s[j+1:])
   118  		if err != nil {
   119  			panic(err)
   120  		}
   121  		return base.MakeInternalKey([]byte(s[:j]), uint64(seq), InternalKeyKindSet)
   122  	}
   123  	w := &blockWriter{}
   124  	for k, e := range strings.Split(strings.TrimSpace("a:1,b:2,c:3,d:4"), ",") {
   125  		w.add(makeIkey(e), []byte(fmt.Sprintf("hello"+strconv.Itoa(k+100))))
   126  	}
   127  	iter, err := newBlockIter(bytes.Compare, w.finish())
   128  	if err != nil {
   129  		panic(err)
   130  	}
   131  	fi, fv := iter.First()
   132  	fmt.Println("first:", fi, string(fv))
   133  	si, sv := iter.Next()
   134  	fmt.Println("second:", si, string(sv))
   135  }
   136  
   137  func TestByteReuse(t *testing.T) {
   138  	buf := make([]byte, 10)
   139  	for _, indexBH := range []BlockHandle{{4, 6}, {18, 3}, {9999, 8888}, {19923892, 2378237}, {6, 7}, {2893824823, 239924829}, {88, 35}} {
   140  		buf2 := make([]byte, 10)
   141  		encodeBlockHandle(buf, indexBH)
   142  		encodeBlockHandle(buf2, indexBH)
   143  		if !bytes.Equal(buf, buf2) {
   144  			fmt.Printf("buf1:%+v\nbuf2:%+v \n", buf, buf2)
   145  		}
   146  	}
   147  	fmt.Println("done")
   148  }
   149  
   150  func TestWriterUpdateIndex(t *testing.T) {
   151  	w := &Writer{
   152  		indexHash:    make(map[uint32]*hashHandle, 1<<18),
   153  		indexArray:   make([]hashHandle, 1<<18),
   154  		conflictKeys: make(map[string]BlockHandle, 10),
   155  	}
   156  
   157  	key1 := []byte("key1")
   158  	w.updateHash(base.MakeInternalKey(key1, 1, InternalKeyKindSet), 100, BlockHandle{1, 1})
   159  	key2 := []byte("key2")
   160  	w.updateHash(base.MakeInternalKey(key2, 1, InternalKeyKindSet), 200, BlockHandle{2, 2})
   161  	require.Equal(t, "key1", string(w.indexHash[100].userKey))
   162  	require.Equal(t, "key2", string(w.indexHash[200].userKey))
   163  	require.Equal(t, uint32(1), w.indexHash[100].bh.Offset)
   164  	require.Equal(t, uint32(1), w.indexHash[100].bh.Length)
   165  	require.Equal(t, uint32(2), w.indexHash[200].bh.Offset)
   166  	require.Equal(t, uint32(2), w.indexHash[200].bh.Length)
   167  	require.Equal(t, 2, len(w.indexHash))
   168  	require.Equal(t, 0, len(w.conflictKeys))
   169  
   170  	w.updateHash(base.MakeInternalKey(key1, 2, InternalKeyKindSet), 100, BlockHandle{3, 3})
   171  	require.Equal(t, uint32(3), w.indexHash[100].bh.Offset)
   172  	require.Equal(t, uint32(3), w.indexHash[100].bh.Length)
   173  	require.Equal(t, false, w.indexHash[100].conflict)
   174  
   175  	key11 := []byte("key11")
   176  	w.updateHash(base.MakeInternalKey(key11, 3, InternalKeyKindSet), 100, BlockHandle{4, 4})
   177  	require.Equal(t, true, w.indexHash[100].conflict)
   178  	require.Equal(t, 2, len(w.conflictKeys))
   179  	require.Equal(t, uint32(3), w.conflictKeys[unsafe2.String(key1)].Offset)
   180  	require.Equal(t, uint32(3), w.conflictKeys[unsafe2.String(key1)].Length)
   181  	require.Equal(t, uint32(4), w.conflictKeys[unsafe2.String(key11)].Offset)
   182  	require.Equal(t, uint32(4), w.conflictKeys[unsafe2.String(key11)].Length)
   183  
   184  	key111 := []byte("key111")
   185  	w.updateHash(base.MakeInternalKey(key111, 4, InternalKeyKindSet), 100, BlockHandle{5, 5})
   186  	w.updateHash(base.MakeInternalKey(key1, 5, InternalKeyKindSet), 100, BlockHandle{6, 6})
   187  	require.Equal(t, true, w.indexHash[100].conflict)
   188  	require.Equal(t, 3, len(w.conflictKeys))
   189  	require.Equal(t, uint32(6), w.conflictKeys[unsafe2.String(key1)].Offset)
   190  	require.Equal(t, uint32(6), w.conflictKeys[unsafe2.String(key1)].Length)
   191  	require.Equal(t, uint32(4), w.conflictKeys[unsafe2.String(key11)].Offset)
   192  	require.Equal(t, uint32(4), w.conflictKeys[unsafe2.String(key11)].Length)
   193  	require.Equal(t, uint32(5), w.conflictKeys[unsafe2.String(key111)].Offset)
   194  	require.Equal(t, uint32(5), w.conflictKeys[unsafe2.String(key111)].Length)
   195  }