github.com/df-mc/goleveldb@v1.1.9/leveldb/batch_test.go (about) 1 // Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com> 2 // All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style license that can be 5 // found in the LICENSE file. 6 7 package leveldb 8 9 import ( 10 "bytes" 11 "fmt" 12 "testing" 13 "testing/quick" 14 15 "github.com/df-mc/goleveldb/leveldb/testutil" 16 ) 17 18 func TestBatchHeader(t *testing.T) { 19 f := func(seq uint64, length uint32) bool { 20 encoded := encodeBatchHeader(nil, seq, int(length)) 21 decSeq, decLength, err := decodeBatchHeader(encoded) 22 return err == nil && decSeq == seq && decLength == int(length) 23 } 24 config := &quick.Config{ 25 Rand: testutil.NewRand(), 26 } 27 if err := quick.Check(f, config); err != nil { 28 t.Error(err) 29 } 30 } 31 32 type batchKV struct { 33 kt keyType 34 k, v []byte 35 } 36 37 func TestBatch(t *testing.T) { 38 var ( 39 kvs []batchKV 40 internalLen int 41 ) 42 batch := new(Batch) 43 rbatch := new(Batch) 44 abatch := new(Batch) 45 testBatch := func(i int, kt keyType, k, v []byte) error { 46 kv := kvs[i] 47 if kv.kt != kt { 48 return fmt.Errorf("invalid key type, index=%d: %d vs %d", i, kv.kt, kt) 49 } 50 if !bytes.Equal(kv.k, k) { 51 return fmt.Errorf("invalid key, index=%d", i) 52 } 53 if !bytes.Equal(kv.v, v) { 54 return fmt.Errorf("invalid value, index=%d", i) 55 } 56 return nil 57 } 58 f := func(ktr uint8, k, v []byte) bool { 59 kt := keyType(ktr % 2) 60 if kt == keyTypeVal { 61 batch.Put(k, v) 62 rbatch.Put(k, v) 63 kvs = append(kvs, batchKV{kt: kt, k: k, v: v}) 64 internalLen += len(k) + len(v) + 8 65 } else { 66 batch.Delete(k) 67 rbatch.Delete(k) 68 kvs = append(kvs, batchKV{kt: kt, k: k}) 69 internalLen += len(k) + 8 70 } 71 if batch.Len() != len(kvs) { 72 t.Logf("batch.Len: %d vs %d", len(kvs), batch.Len()) 73 return false 74 } 75 if batch.internalLen != internalLen { 76 t.Logf("abatch.internalLen: %d vs %d", internalLen, batch.internalLen) 77 return false 78 } 79 if len(kvs)%1000 == 0 { 80 if err := batch.replayInternal(testBatch); err != nil { 81 t.Logf("batch.replayInternal: %v", err) 82 return false 83 } 84 85 abatch.append(rbatch) 86 rbatch.Reset() 87 if abatch.Len() != len(kvs) { 88 t.Logf("abatch.Len: %d vs %d", len(kvs), abatch.Len()) 89 return false 90 } 91 if abatch.internalLen != internalLen { 92 t.Logf("abatch.internalLen: %d vs %d", internalLen, abatch.internalLen) 93 return false 94 } 95 if err := abatch.replayInternal(testBatch); err != nil { 96 t.Logf("abatch.replayInternal: %v", err) 97 return false 98 } 99 100 nbatch := new(Batch) 101 if err := nbatch.Load(batch.Dump()); err != nil { 102 t.Logf("nbatch.Load: %v", err) 103 return false 104 } 105 if nbatch.Len() != len(kvs) { 106 t.Logf("nbatch.Len: %d vs %d", len(kvs), nbatch.Len()) 107 return false 108 } 109 if nbatch.internalLen != internalLen { 110 t.Logf("nbatch.internalLen: %d vs %d", internalLen, nbatch.internalLen) 111 return false 112 } 113 if err := nbatch.replayInternal(testBatch); err != nil { 114 t.Logf("nbatch.replayInternal: %v", err) 115 return false 116 } 117 } 118 if len(kvs)%10000 == 0 { 119 nbatch := new(Batch) 120 if err := batch.Replay(nbatch); err != nil { 121 t.Logf("batch.Replay: %v", err) 122 return false 123 } 124 if nbatch.Len() != len(kvs) { 125 t.Logf("nbatch.Len: %d vs %d", len(kvs), nbatch.Len()) 126 return false 127 } 128 if nbatch.internalLen != internalLen { 129 t.Logf("nbatch.internalLen: %d vs %d", internalLen, nbatch.internalLen) 130 return false 131 } 132 if err := nbatch.replayInternal(testBatch); err != nil { 133 t.Logf("nbatch.replayInternal: %v", err) 134 return false 135 } 136 } 137 return true 138 } 139 config := &quick.Config{ 140 MaxCount: 40000, 141 Rand: testutil.NewRand(), 142 } 143 if err := quick.Check(f, config); err != nil { 144 t.Error(err) 145 } 146 t.Logf("length=%d internalLen=%d", len(kvs), internalLen) 147 }