Skip to content

Commit 4c77062

Browse files
committed
ethdb/rocksdb: fixed iterator range issue
1 parent dbdc2c0 commit 4c77062

File tree

1 file changed

+42
-21
lines changed

1 file changed

+42
-21
lines changed

ethdb/rocksdb/rocksdb.go

+42-21
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package rocksdb
66

77
// #include <stdlib.h>
8+
// #include <string.h>
89
// #include "rocksdb/c.h"
910
import "C"
1011

@@ -37,8 +38,8 @@ type RDBIterator struct {
3738
it *C.rocksdb_iterator_t
3839
opts *C.rocksdb_readoptions_t
3940
first bool
40-
lowerBound []byte
41-
upperBound []byte
41+
lowerBound *C.char
42+
upperBound *C.char
4243
}
4344

4445
func cerror(cerr *C.char) error {
@@ -159,16 +160,29 @@ func (db *RDBDatabase) Delete(key []byte) error {
159160
return nil
160161
}
161162

162-
func (db *RDBDatabase) NewIterator(prefix, start []byte) ethdb.Iterator {
163-
begin := prefix
164-
end := incrBytes(begin)
165-
begin = append(begin, start...)
163+
func memdup(b []byte) *C.char {
164+
x := (*C.char)(C.malloc(C.size_t(len(b))))
165+
C.memcpy(unsafe.Pointer(x), unsafe.Pointer(b2c(b)), C.size_t(len(b)))
166+
return x
167+
}
166168

169+
func (db *RDBDatabase) NewIterator(prefix, start []byte) ethdb.Iterator {
170+
var begin, end []byte
171+
begin = prefix
172+
if len(start) > 0 {
173+
begin = append(begin, start...)
174+
}
175+
if len(prefix) > 0 {
176+
end = incrBytes(prefix)
177+
}
178+
var lowerBound, upperBound *C.char
167179
opts := C.rocksdb_readoptions_create()
168180
if len(begin) > 0 {
169-
lowerBound := b2c(begin)
181+
lowerBound = memdup(begin)
170182
C.rocksdb_readoptions_set_iterate_lower_bound(opts, lowerBound, C.size_t(len(begin)))
171-
upperBound := b2c(end)
183+
}
184+
if len(end) > 0 {
185+
upperBound = memdup(end)
172186
C.rocksdb_readoptions_set_iterate_upper_bound(opts, upperBound, C.size_t(len(end)))
173187
}
174188
it := C.rocksdb_create_iterator(db.db, opts)
@@ -179,23 +193,23 @@ func (db *RDBDatabase) NewIterator(prefix, start []byte) ethdb.Iterator {
179193
first: true,
180194
}
181195
if len(begin) > 0 {
182-
rit.lowerBound = begin
183-
rit.upperBound = end
196+
rit.lowerBound = lowerBound
197+
rit.upperBound = upperBound
184198
}
185199
return rit
186200
}
187201

188202
func (db *RDBDatabase) NewIteratorWithStart(start []byte) ethdb.Iterator {
189203
opts := C.rocksdb_readoptions_create()
190-
lowerBound := b2c(start)
204+
lowerBound := memdup(start)
191205
C.rocksdb_readoptions_set_iterate_lower_bound(opts, lowerBound, C.size_t(len(start)))
192206
it := C.rocksdb_create_iterator(db.db, opts)
193207
C.rocksdb_iter_seek_to_first(it)
194208
return &RDBIterator{
195209
it: it,
196210
opts: opts,
197211
first: true,
198-
lowerBound: start,
212+
lowerBound: lowerBound,
199213
}
200214
}
201215

@@ -204,18 +218,18 @@ func (db *RDBDatabase) NewIteratorWithPrefix(prefix []byte) ethdb.Iterator {
204218
end := incrBytes(start)
205219

206220
opts := C.rocksdb_readoptions_create()
207-
lowerBound := b2c(start)
221+
lowerBound := memdup(start)
208222
C.rocksdb_readoptions_set_iterate_lower_bound(opts, lowerBound, C.size_t(len(start)))
209-
upperBound := b2c(end)
223+
upperBound := memdup(end)
210224
C.rocksdb_readoptions_set_iterate_upper_bound(opts, upperBound, C.size_t(len(end)))
211225
it := C.rocksdb_create_iterator(db.db, opts)
212226
C.rocksdb_iter_seek_to_first(it)
213227
return &RDBIterator{
214228
it: it,
215229
opts: opts,
216230
first: true,
217-
lowerBound: start,
218-
upperBound: end,
231+
lowerBound: lowerBound,
232+
upperBound: upperBound,
219233
}
220234
}
221235

@@ -284,6 +298,12 @@ func (it *RDBIterator) Release() {
284298
if it.opts != nil {
285299
C.rocksdb_readoptions_destroy(it.opts)
286300
}
301+
if it.lowerBound != nil {
302+
C.free(unsafe.Pointer(it.lowerBound))
303+
}
304+
if it.upperBound != nil {
305+
C.free(unsafe.Pointer(it.upperBound))
306+
}
287307
it.it, it.opts, it.lowerBound, it.upperBound = nil, nil, nil, nil
288308
}
289309

@@ -312,10 +332,10 @@ func (db *RDBDatabase) Meter(prefix string) {
312332
func (db *RDBDatabase) NewBatch() ethdb.Batch {
313333
b := C.rocksdb_writebatch_create()
314334
bb := &rdbBatch{db: db.db, b: b, wopts: db.wopts, data: nil}
315-
runtime.SetFinalizer(bb, func(bb *rdbBatch) {
316-
if bb.b != nil {
317-
C.rocksdb_writebatch_destroy(bb.b)
318-
bb.b = nil
335+
runtime.SetFinalizer(bb, func(bbb *rdbBatch) {
336+
if bbb.b != nil {
337+
C.rocksdb_writebatch_destroy(bbb.b)
338+
bbb.b = nil
319339
}
320340
})
321341
return bb
@@ -368,7 +388,8 @@ func (b *rdbBatch) ValueSize() int {
368388
}
369389

370390
func (b *rdbBatch) Reset() {
371-
C.rocksdb_writebatch_clear(b.b)
391+
C.rocksdb_writebatch_destroy(b.b)
392+
b.b = C.rocksdb_writebatch_create()
372393
b.data = nil
373394
b.size = 0
374395
}

0 commit comments

Comments
 (0)