Commit 7dd51afb authored by Jeromy Johnson's avatar Jeromy Johnson Committed by GitHub

Merge pull request #46 from ipfs/feat/leveldb-batching

implement batching for leveldb
parents 9b48c4ee 92a2e45d
language: go language: go
go: go:
- 1.6.2 - 1.6.3
- release
- tip - tip
script: script:
......
...@@ -99,7 +99,7 @@ func (fs *Datastore) makePrefixDirNoSync(dir string) error { ...@@ -99,7 +99,7 @@ func (fs *Datastore) makePrefixDirNoSync(dir string) error {
return nil return nil
} }
var putMaxRetries = 3 var putMaxRetries = 6
func (fs *Datastore) Put(key datastore.Key, value interface{}) error { func (fs *Datastore) Put(key datastore.Key, value interface{}) error {
val, ok := value.([]byte) val, ok := value.([]byte)
...@@ -108,14 +108,14 @@ func (fs *Datastore) Put(key datastore.Key, value interface{}) error { ...@@ -108,14 +108,14 @@ func (fs *Datastore) Put(key datastore.Key, value interface{}) error {
} }
var err error var err error
for i := 0; i < putMaxRetries; i++ { for i := 1; i <= putMaxRetries; i++ {
err = fs.doPut(key, val) err = fs.doPut(key, val)
if err == nil { if err == nil {
return nil break
} }
if !strings.Contains(err.Error(), "too many open files") { if !strings.Contains(err.Error(), "too many open files") {
return err break
} }
log.Errorf("too many open files, retrying in %dms", 100*i) log.Errorf("too many open files, retrying in %dms", 100*i)
......
...@@ -147,14 +147,40 @@ func (d *datastore) runQuery(worker goprocess.Process, qrb *dsq.ResultBuilder) { ...@@ -147,14 +147,40 @@ func (d *datastore) runQuery(worker goprocess.Process, qrb *dsq.ResultBuilder) {
} }
} }
func (d *datastore) Batch() (ds.Batch, error) {
// TODO: implement batch on leveldb
return nil, ds.ErrBatchUnsupported
}
// LevelDB needs to be closed. // LevelDB needs to be closed.
func (d *datastore) Close() (err error) { func (d *datastore) Close() (err error) {
return d.DB.Close() return d.DB.Close()
} }
func (d *datastore) IsThreadSafe() {} func (d *datastore) IsThreadSafe() {}
type leveldbBatch struct {
b *leveldb.Batch
db *leveldb.DB
}
func (d *datastore) Batch() (ds.Batch, error) {
return &leveldbBatch{
b: new(leveldb.Batch),
db: d.DB,
}, nil
}
func (b *leveldbBatch) Put(key ds.Key, value interface{}) error {
val, ok := value.([]byte)
if !ok {
return ds.ErrInvalidType
}
b.b.Put(key.Bytes(), val)
return nil
}
func (b *leveldbBatch) Commit() error {
return b.db.Write(b.b, nil)
}
func (b *leveldbBatch) Delete(key ds.Key) error {
b.b.Delete(key.Bytes())
return nil
}
...@@ -122,3 +122,36 @@ func expectMatches(t *testing.T, expect []string, actualR dsq.Results) { ...@@ -122,3 +122,36 @@ func expectMatches(t *testing.T, expect []string, actualR dsq.Results) {
} }
} }
} }
func TestBatching(t *testing.T) {
d, done := newDS(t)
defer done()
b, err := d.Batch()
if err != nil {
t.Fatal(err)
}
for k, v := range testcases {
err := b.Put(ds.NewKey(k), []byte(v))
if err != nil {
t.Fatal(err)
}
}
err = b.Commit()
if err != nil {
t.Fatal(err)
}
for k, v := range testcases {
val, err := d.Get(ds.NewKey(k))
if err != nil {
t.Fatal(err)
}
if v != string(val.([]byte)) {
t.Fatal("got wrong data!")
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment