0
0

fix bug in curent goleveldb (must copy during iteration)

also changed over to mschoch fork of goleveldb (temporary)

the change to my fork is pending some read-only issues described
here:  https://github.com/syndtr/goleveldb/issues/111

hopefully we can find a path forward, and get that addressed upstream
This commit is contained in:
Marty Schoch 2015-07-06 17:57:21 -04:00
parent 7f0961424d
commit bf80f4628e
7 changed files with 128 additions and 11 deletions

View File

@ -11,7 +11,7 @@ package goleveldb
import (
"github.com/blevesearch/bleve/index/store"
"github.com/syndtr/goleveldb/leveldb"
"github.com/mschoch/goleveldb/leveldb"
)
type Batch struct {

View File

@ -10,13 +10,15 @@
package goleveldb
import (
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/iterator"
"github.com/mschoch/goleveldb/leveldb"
"github.com/mschoch/goleveldb/leveldb/iterator"
)
type Iterator struct {
store *Store
iterator iterator.Iterator
copyk []byte
copyv []byte
}
func newIterator(store *Store) *Iterator {
@ -40,14 +42,20 @@ func newIteratorWithSnapshot(store *Store, snapshot *leveldb.Snapshot) *Iterator
}
func (ldi *Iterator) SeekFirst() {
ldi.copyk = nil
ldi.copyv = nil
ldi.iterator.First()
}
func (ldi *Iterator) Seek(key []byte) {
ldi.copyk = nil
ldi.copyv = nil
ldi.iterator.Seek(key)
}
func (ldi *Iterator) Next() {
ldi.copyk = nil
ldi.copyv = nil
ldi.iterator.Next()
}
@ -59,11 +67,21 @@ func (ldi *Iterator) Current() ([]byte, []byte, bool) {
}
func (ldi *Iterator) Key() []byte {
return ldi.iterator.Key()
k := ldi.iterator.Key()
if ldi.copyk == nil {
ldi.copyk = make([]byte, len(k))
copy(ldi.copyk, k)
}
return ldi.copyk
}
func (ldi *Iterator) Value() []byte {
return ldi.iterator.Value()
v := ldi.iterator.Value()
if ldi.copyv == nil {
ldi.copyv = make([]byte, len(v))
copy(ldi.copyv, v)
}
return ldi.copyv
}
func (ldi *Iterator) Valid() bool {
@ -71,5 +89,7 @@ func (ldi *Iterator) Valid() bool {
}
func (ldi *Iterator) Close() error {
ldi.copyk = nil
ldi.copyv = nil
return nil
}

View File

@ -11,7 +11,7 @@ package goleveldb
import (
"github.com/blevesearch/bleve/index/store"
"github.com/syndtr/goleveldb/leveldb"
"github.com/mschoch/goleveldb/leveldb"
)
type Reader struct {

View File

@ -15,9 +15,9 @@ import (
"github.com/blevesearch/bleve/index/store"
"github.com/blevesearch/bleve/registry"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/filter"
"github.com/syndtr/goleveldb/leveldb/opt"
"github.com/mschoch/goleveldb/leveldb"
"github.com/mschoch/goleveldb/leveldb/filter"
"github.com/mschoch/goleveldb/leveldb/opt"
)
const Name = "goleveldb"
@ -132,6 +132,11 @@ func init() {
func applyConfig(o *opt.Options, config map[string]interface{}) (
*opt.Options, error) {
ro, ok := config["read_only"].(bool)
if ok {
o.ReadOnly = ro
}
cim, ok := config["create_if_missing"].(bool)
if ok {
o.ErrorIfMissing = !cim

View File

@ -47,6 +47,32 @@ func TestLevelDBStore(t *testing.T) {
CommonTestKVStore(t, s)
}
func TestLevelDBStoreIterator(t *testing.T) {
defer func() {
err := os.RemoveAll("test")
if err != nil {
t.Fatal(err)
}
}()
s, err := New("test", leveldbTestOptions)
if err != nil {
t.Fatal(err)
}
err = s.Open()
if err != nil {
t.Fatal(err)
}
defer func() {
err := s.Close()
if err != nil {
t.Fatal(err)
}
}()
CommonTestKVStoreIterator(t, s)
}
func TestReaderIsolation(t *testing.T) {
defer func() {
err := os.RemoveAll("test")
@ -294,3 +320,69 @@ func CommonTestReaderIsolation(t *testing.T, s store.KVStore) {
}
}
func CommonTestKVStoreIterator(t *testing.T, s store.KVStore) {
writer, err := s.Writer()
if err != nil {
t.Error(err)
}
data := []struct {
k []byte
v []byte
}{
{[]byte("t\x09\x00paint\xff/sponsor/gold/thumbtack/"), []byte("a")},
{[]byte("t\x09\x00party\xff/sponsor/gold/thumbtack/"), []byte("a")},
{[]byte("t\x09\x00personal\xff/sponsor/gold/thumbtack/"), []byte("a")},
{[]byte("t\x09\x00plan\xff/sponsor/gold/thumbtack/"), []byte("a")},
}
batch := writer.NewBatch()
for _, d := range data {
batch.Set(d.k, d.v)
}
err = batch.Execute()
if err != nil {
t.Fatal(err)
}
err = writer.Close()
if err != nil {
t.Fatal(err)
}
reader, err := s.Reader()
if err != nil {
t.Error(err)
}
defer func() {
err := reader.Close()
if err != nil {
t.Fatal(err)
}
}()
it := reader.Iterator([]byte("a"))
keys := make([][]byte, 0, len(data))
key, _, valid := it.Current()
for valid {
keys = append(keys, key)
it.Next()
key, _, valid = it.Current()
}
if len(keys) != len(data) {
t.Errorf("expected same number of keys, got %d != %d", len(keys), len(data))
}
for i, dk := range data {
if !reflect.DeepEqual(dk.k, keys[i]) {
t.Errorf("expected key %s got %s", dk.k, keys[i])
}
}
err = it.Close()
if err != nil {
t.Fatal(err)
}
}

View File

@ -10,7 +10,7 @@
package goleveldb
import (
"github.com/syndtr/goleveldb/leveldb/opt"
"github.com/mschoch/goleveldb/leveldb/opt"
)
func defaultWriteOptions() *opt.WriteOptions {

View File

@ -11,7 +11,7 @@ package goleveldb
import (
"github.com/blevesearch/bleve/index/store"
"github.com/syndtr/goleveldb/leveldb"
"github.com/mschoch/goleveldb/leveldb"
)
type Writer struct {