github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/internal/cache/lfucache/array_table_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 lfucache 16 17 import ( 18 "bytes" 19 "encoding/binary" 20 "fmt" 21 "sort" 22 "testing" 23 "time" 24 25 "github.com/stretchr/testify/require" 26 ) 27 28 func TestArrayTable_Set(t *testing.T) { 29 num := 100 30 size := 52 * num 31 at := newArrayTable(1, size) 32 for i := 0; i < num; i++ { 33 key := []byte(fmt.Sprintf("cacheTestAtKey_%d", i)) 34 value := []byte(fmt.Sprintf("cacheTestAtValue_%d", i)) 35 if err := at.add(key, value); err != nil { 36 t.Fatalf("add err key:%s err:%v", string(key), err) 37 } 38 } 39 40 require.Equal(t, num, at.count()) 41 42 for i := 0; i < num; i++ { 43 expKey := []byte(fmt.Sprintf("cacheTestAtKey_%d", i)) 44 expValue := []byte(fmt.Sprintf("cacheTestAtValue_%d", i)) 45 key, vaule := at.getKV(i) 46 require.Equal(t, expKey, key) 47 require.Equal(t, expValue, vaule) 48 } 49 } 50 51 func TestArrayTable_VS_MAP(t *testing.T) { 52 var buf [4]byte 53 num := uint32(1 << 20) 54 size := arrayTableEntrySize(4, 4) * int(num) 55 at := newArrayTable(1, size) 56 57 bt := time.Now() 58 i := uint32(0) 59 for ; i < num; i++ { 60 binary.BigEndian.PutUint32(buf[:], i) 61 if err := at.add(buf[:], buf[:]); err != nil { 62 t.Fatalf("add err key:%s err:%v", buf, err) 63 } 64 } 65 et := time.Since(bt) 66 fmt.Printf("arrtable add(include crc32, if annotate crc32, more faster then hashmap) time cost = %v\n", et) 67 68 bt = time.Now() 69 i = uint32(0) 70 for ; i < num; i++ { 71 binary.BigEndian.PutUint32(buf[:], i) 72 val, _, _ := at.get(buf[:]) 73 if !bytes.Equal(buf[:], val[:]) { 74 t.Fatalf("arrtable get err key:%s\n", buf) 75 } 76 } 77 et = time.Since(bt) 78 fmt.Printf("arrtable get time cost = %v\n", et) 79 80 bt = time.Now() 81 i = uint32(0) 82 for ; i < num; i++ { 83 binary.BigEndian.PutUint32(buf[:], i) 84 iter := at.newIter(nil) 85 _, iterValue := iter.SeekGE(buf[:]) 86 if !bytes.Equal(buf[:], iterValue[:]) { 87 t.Fatalf("arrtable use-iter-ßget err key:%s\n", buf) 88 } 89 iter.Close() 90 } 91 et = time.Since(bt) 92 fmt.Printf("arrtable use-iter-get time cost = %v\n", et) 93 94 hashmap := make(map[uint32]uint32, 1<<10) 95 bt = time.Now() 96 i = uint32(0) 97 for ; i < num; i++ { 98 binary.BigEndian.PutUint32(buf[:], i) 99 hashmap[i] = i 100 } 101 et = time.Since(bt) 102 fmt.Printf("hashmap add time cost = %v\n", et) 103 104 bt = time.Now() 105 i = uint32(0) 106 for ; i < num; i++ { 107 binary.BigEndian.PutUint32(buf[:], i) 108 if _, ok := hashmap[i]; !ok { 109 t.Fatalf("hashmap get err key:%s\n", buf) 110 } 111 } 112 et = time.Since(bt) 113 fmt.Printf("hashmap get time cost = %v\n", et) 114 } 115 116 type keySlice [][]byte 117 118 func (x keySlice) Len() int { return len(x) } 119 func (x keySlice) Less(i, j int) bool { return bytes.Compare(x[i], x[j]) == -1 } 120 func (x keySlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 121 122 func TestArrayTable_Iter(t *testing.T) { 123 num := 100000 124 size := 52 * num 125 at := newArrayTable(1, size) 126 keys := make(keySlice, num, num) 127 for i := 0; i < num; i++ { 128 keys[i] = []byte(fmt.Sprintf("cacheTestAtKey_%d", i)) 129 } 130 131 sort.Sort(keys) 132 for i := 0; i < num; i++ { 133 key := keys[i] 134 if err := at.add(key, key); err != nil { 135 t.Fatalf("add err key:%s err:%v", string(key), err) 136 } 137 } 138 139 var bytesFlushed *uint64 140 iter := at.newFlushIter(nil, bytesFlushed) 141 key, vaule := iter.First() 142 for i := 0; i < num; i++ { 143 expKey := keys[i] 144 require.Equal(t, expKey, key.UserKey) 145 require.Equal(t, expKey, vaule) 146 key, vaule = iter.Next() 147 } 148 require.NoError(t, iter.Close()) 149 150 seekExist := func(skey []byte) { 151 ik, v := at.seek(skey) 152 require.Equal(t, skey, ik.UserKey) 153 require.Equal(t, skey, v) 154 } 155 seekNotExist := func(skey []byte) { 156 ik, _ := at.seek(skey) 157 require.Equal(t, (*internalKey)(nil), ik) 158 } 159 160 for _, v := range []int{7, 71, 711} { 161 seekExist([]byte(fmt.Sprintf("cacheTestAtKey_%d", v))) 162 } 163 for _, v := range []int{100007, 100071, 100711} { 164 seekNotExist([]byte(fmt.Sprintf("cacheTestAtKey_%d", v))) 165 } 166 }