github.com/turingchain2020/turingchain@v1.1.21/common/db/go_level_db_test.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package db 6 7 import ( 8 "bytes" 9 "encoding/binary" 10 "fmt" 11 "io/ioutil" 12 "os" 13 "testing" 14 15 "github.com/turingchain2020/turingchain/common" 16 17 "github.com/stretchr/testify/assert" 18 "github.com/stretchr/testify/require" 19 ) 20 21 // leveldb迭代器测试 22 func TestGoLevelDBIterator(t *testing.T) { 23 dir, err := ioutil.TempDir("", "goleveldb") 24 require.NoError(t, err) 25 t.Log(dir) 26 leveldb, err := NewGoLevelDB("goleveldb", dir, 128) 27 require.NoError(t, err) 28 defer leveldb.Close() 29 testDBIterator(t, leveldb) 30 } 31 32 func TestGoLevelDBIteratorAll(t *testing.T) { 33 dir, err := ioutil.TempDir("", "goleveldb") 34 require.NoError(t, err) 35 t.Log(dir) 36 leveldb, err := NewGoLevelDB("goleveldb", dir, 128) 37 require.NoError(t, err) 38 defer leveldb.Close() 39 testDBIteratorAllKey(t, leveldb) 40 } 41 42 func TestGoLevelDBIteratorReserverExample(t *testing.T) { 43 dir, err := ioutil.TempDir("", "goleveldb") 44 require.NoError(t, err) 45 t.Log(dir) 46 leveldb, err := NewGoLevelDB("goleveldb", dir, 128) 47 require.NoError(t, err) 48 defer leveldb.Close() 49 testDBIteratorReserverExample(t, leveldb) 50 } 51 52 func TestGoLevelDBIteratorDel(t *testing.T) { 53 dir, err := ioutil.TempDir("", "goleveldb") 54 require.NoError(t, err) 55 t.Log(dir) 56 57 leveldb, err := NewGoLevelDB("goleveldb", dir, 128) 58 require.NoError(t, err) 59 defer leveldb.Close() 60 61 testDBIteratorDel(t, leveldb) 62 } 63 64 func TestLevelDBBatch(t *testing.T) { 65 dir, err := ioutil.TempDir("", "goleveldb") 66 require.NoError(t, err) 67 t.Log(dir) 68 69 leveldb, err := NewGoLevelDB("goleveldb", dir, 128) 70 require.NoError(t, err) 71 defer leveldb.Close() 72 testBatch(t, leveldb) 73 } 74 75 func TestLevelDBTransaction(t *testing.T) { 76 dir, err := ioutil.TempDir("", "goleveldb") 77 require.NoError(t, err) 78 t.Log(dir) 79 80 leveldb, err := NewGoLevelDB("goleveldb", dir, 128) 81 require.NoError(t, err) 82 defer leveldb.Close() 83 testTransaction(t, leveldb) 84 } 85 86 // leveldb边界测试 87 func TestGoLevelDBBoundary(t *testing.T) { 88 dir, err := ioutil.TempDir("", "goleveldb") 89 require.NoError(t, err) 90 t.Log(dir) 91 92 leveldb, err := NewGoLevelDB("goleveldb", dir, 128) 93 require.NoError(t, err) 94 defer leveldb.Close() 95 96 testDBBoundary(t, leveldb) 97 } 98 99 func BenchmarkLevelDBBatchWrites(b *testing.B) { 100 dir, err := ioutil.TempDir("", "example") 101 assert.Nil(b, err) 102 defer os.RemoveAll(dir) 103 db, err := NewGoLevelDB("goleveldb", dir, 100) 104 assert.Nil(b, err) 105 batch := db.NewBatch(true) 106 b.ResetTimer() 107 for i := 0; i < b.N; i++ { 108 b.StopTimer() 109 key := string(common.GetRandBytes(20, 64)) 110 value := fmt.Sprintf("v%d", i) 111 b.StartTimer() 112 batch.Set([]byte(key), []byte(value)) 113 if i > 0 && i%10000 == 0 { 114 err := batch.Write() 115 assert.Nil(b, err) 116 batch = db.NewBatch(true) 117 } 118 } 119 err = batch.Write() 120 assert.Nil(b, err) 121 b.StopTimer() 122 } 123 124 func BenchmarkLevelDBBatchWrites1k(b *testing.B) { 125 benchmarkBatchWrites(b, 1) 126 } 127 128 func BenchmarkLevelDBBatchWrites16k(b *testing.B) { 129 benchmarkBatchWrites(b, 16) 130 } 131 132 func BenchmarkLevelDBBatchWrites256k(b *testing.B) { 133 benchmarkBatchWrites(b, 256) 134 } 135 136 func BenchmarkLevelDBBatchWrites1M(b *testing.B) { 137 benchmarkBatchWrites(b, 1024) 138 } 139 140 //func BenchmarkLevelDBBatchWrites4M(b *testing.B) { 141 // benchmarkBatchWrites(b, 1024*4) 142 //} 143 144 func benchmarkBatchWrites(b *testing.B, size int) { 145 dir, err := ioutil.TempDir("", "example") 146 assert.Nil(b, err) 147 defer os.RemoveAll(dir) 148 db, err := NewGoLevelDB("goleveldb", dir, 100) 149 assert.Nil(b, err) 150 batch := db.NewBatch(true) 151 b.ResetTimer() 152 for i := 0; i < b.N; i++ { 153 b.StopTimer() 154 key := common.GetRandBytes(20, 64) 155 value := common.GetRandBytes(size*1024, size*1024) 156 b.StartTimer() 157 batch.Set(key, value) 158 if i > 0 && i%100 == 0 { 159 err := batch.Write() 160 assert.Nil(b, err) 161 batch = db.NewBatch(true) 162 } 163 } 164 err = batch.Write() 165 assert.Nil(b, err) 166 b.StopTimer() 167 } 168 169 func BenchmarkLevelDBRandomReads1K(b *testing.B) { 170 benchmarkLevelDBRandomReads(b, 1) 171 } 172 173 func BenchmarkLevelDBRandomReads16K(b *testing.B) { 174 benchmarkLevelDBRandomReads(b, 16) 175 } 176 177 func BenchmarkLevelDBRandomReads256K(b *testing.B) { 178 benchmarkLevelDBRandomReads(b, 256) 179 } 180 181 func BenchmarkLevelDBRandomReads1M(b *testing.B) { 182 benchmarkLevelDBRandomReads(b, 1024) 183 } 184 185 func benchmarkLevelDBRandomReads(b *testing.B, size int) { 186 dir, err := ioutil.TempDir("", "example") 187 assert.Nil(b, err) 188 defer os.RemoveAll(dir) 189 db, err := NewGoLevelDB("goleveldb", dir, 100) 190 assert.Nil(b, err) 191 batch := db.NewBatch(true) 192 var keys [][]byte 193 for i := 0; i < 32*1024/size; i++ { 194 key := common.GetRandBytes(20, 64) 195 value := common.GetRandBytes(size*1024, size*1024) 196 batch.Set(key, value) 197 keys = append(keys, key) 198 if batch.ValueSize() > 1<<20 { 199 err := batch.Write() 200 assert.Nil(b, err) 201 batch = db.NewBatch(true) 202 } 203 } 204 if batch.ValueSize() > 0 { 205 err = batch.Write() 206 assert.Nil(b, err) 207 } 208 209 //开始rand 读取 210 db.Close() 211 db, err = NewGoLevelDB("goleveldb", dir, 1) 212 assert.Nil(b, err) 213 b.ResetTimer() 214 for i := 0; i < b.N; i++ { 215 index := RandInt() % len(keys) 216 key := keys[index] 217 _, err := db.Get(key) 218 assert.Nil(b, err) 219 } 220 b.StopTimer() 221 } 222 223 func BenchmarkLevelDBRandomReadsWrites(b *testing.B) { 224 numItems := int64(1000000) 225 internal := map[int64]int64{} 226 for i := 0; i < int(numItems); i++ { 227 internal[int64(i)] = int64(0) 228 } 229 dir := fmt.Sprintf("test_%x", RandStr(12)) 230 defer os.RemoveAll(dir) 231 db, err := NewGoLevelDB("goleveldb", dir, 1000) 232 if err != nil { 233 b.Fatal(err.Error()) 234 return 235 } 236 for i := 0; i < b.N; i++ { 237 // Write something 238 { 239 idx := (int64(RandInt()) % numItems) 240 internal[idx]++ 241 val := internal[idx] 242 idxBytes := int642Bytes(idx) 243 valBytes := int642Bytes(val) 244 //fmt.Printf("Set %X -> %X\n", idxBytes, valBytes) 245 db.Set( 246 idxBytes, 247 valBytes, 248 ) 249 } 250 } 251 252 b.ResetTimer() 253 for i := 0; i < b.N; i++ { 254 // Read something 255 { 256 idx := (int64(RandInt()) % numItems) 257 val := internal[idx] 258 idxBytes := int642Bytes(idx) 259 valBytes, _ := db.Get(idxBytes) 260 //fmt.Printf("Get %X -> %X\n", idxBytes, valBytes) 261 if val == 0 { 262 if !bytes.Equal(valBytes, nil) { 263 b.Errorf("Expected %v for %v, got %X", 264 nil, idx, valBytes) 265 break 266 } 267 } else { 268 if len(valBytes) != 8 { 269 b.Errorf("Expected length 8 for %v, got %X", 270 idx, valBytes) 271 break 272 } 273 valGot := bytes2Int64(valBytes) 274 if val != valGot { 275 b.Errorf("Expected %v for %v, got %v", 276 val, idx, valGot) 277 break 278 } 279 } 280 } 281 } 282 b.StopTimer() 283 db.Close() 284 } 285 286 func int642Bytes(i int64) []byte { 287 buf := make([]byte, 8) 288 binary.BigEndian.PutUint64(buf, uint64(i)) 289 return buf 290 } 291 292 func bytes2Int64(buf []byte) int64 { 293 return int64(binary.BigEndian.Uint64(buf)) 294 } 295 296 // leveldb返回值测试 297 func TestGoLevelDBResult(t *testing.T) { 298 dir, err := ioutil.TempDir("", "goleveldb") 299 require.NoError(t, err) 300 t.Log(dir) 301 302 leveldb, err := NewGoLevelDB("goleveldb", dir, 128) 303 require.NoError(t, err) 304 defer leveldb.Close() 305 306 testDBIteratorResult(t, leveldb) 307 }