Unverified Commit 0706d00f authored by Steven Allen's avatar Steven Allen Committed by GitHub

Merge pull request #99 from ipfs/feat/get-size

add a GetSize method
parents 19b8f34d 6196c6a3
3.3.0: QmbQshXLNcCPRUGZv4sBGxnZNAHREA6MKeomkwihNXPZWP 3.4.0: QmaRb5yNXKonhbkpNxNawoydk4N6es6b4fPj19sjEKsh5D
...@@ -88,6 +88,16 @@ func (d *Datastore) Has(k ds.Key) (bool, error) { ...@@ -88,6 +88,16 @@ func (d *Datastore) Has(k ds.Key) (bool, error) {
return d.child.Has(k) return d.child.Has(k)
} }
// GetSize implements Datastore.GetSize
func (d *Datastore) GetSize(k ds.Key) (int, error) {
v, ok := d.buffer[k]
if ok {
return len(v), nil
}
return d.child.GetSize(k)
}
// Query performs a query // Query performs a query
func (d *Datastore) Query(q dsq.Query) (dsq.Results, error) { func (d *Datastore) Query(q dsq.Query) (dsq.Results, error) {
err := d.Flush() err := d.Flush()
......
...@@ -42,6 +42,14 @@ func (d *MapDatastore) Has(key Key) (exists bool, err error) { ...@@ -42,6 +42,14 @@ func (d *MapDatastore) Has(key Key) (exists bool, err error) {
return found, nil return found, nil
} }
// GetSize implements Datastore.GetSize
func (d *MapDatastore) GetSize(key Key) (size int, err error) {
if v, found := d.values[key]; found {
return len(v), nil
}
return -1, ErrNotFound
}
// Delete implements Datastore.Delete // Delete implements Datastore.Delete
func (d *MapDatastore) Delete(key Key) (err error) { func (d *MapDatastore) Delete(key Key) (err error) {
if _, found := d.values[key]; !found { if _, found := d.values[key]; !found {
...@@ -95,6 +103,11 @@ func (d *NullDatastore) Has(key Key) (exists bool, err error) { ...@@ -95,6 +103,11 @@ func (d *NullDatastore) Has(key Key) (exists bool, err error) {
return false, nil return false, nil
} }
// Has implements Datastore.GetSize
func (d *NullDatastore) GetSize(key Key) (size int, err error) {
return -1, ErrNotFound
}
// Delete implements Datastore.Delete // Delete implements Datastore.Delete
func (d *NullDatastore) Delete(key Key) (err error) { func (d *NullDatastore) Delete(key Key) (err error) {
return nil return nil
...@@ -158,6 +171,12 @@ func (d *LogDatastore) Has(key Key) (exists bool, err error) { ...@@ -158,6 +171,12 @@ func (d *LogDatastore) Has(key Key) (exists bool, err error) {
return d.child.Has(key) return d.child.Has(key)
} }
// GetSize implements Datastore.GetSize
func (d *LogDatastore) GetSize(key Key) (size int, err error) {
log.Printf("%s: GetSize %s\n", d.Name, key)
return d.child.GetSize(key)
}
// Delete implements Datastore.Delete // Delete implements Datastore.Delete
func (d *LogDatastore) Delete(key Key) (err error) { func (d *LogDatastore) Delete(key Key) (err error) {
log.Printf("%s: Delete %s\n", d.Name, key) log.Printf("%s: Delete %s\n", d.Name, key)
......
...@@ -52,6 +52,11 @@ type Datastore interface { ...@@ -52,6 +52,11 @@ type Datastore interface {
// The default implementation is found in `GetBackedHas`. // The default implementation is found in `GetBackedHas`.
Has(key Key) (exists bool, err error) Has(key Key) (exists bool, err error)
// GetSize returns the size of the `value` named by `key`.
// In some contexts, it may be much cheaper to only get the size of the
// value rather than retrieving the value itself.
GetSize(key Key) (size int, err error)
// Delete removes the value for given `key`. // Delete removes the value for given `key`.
Delete(key Key) error Delete(key Key) error
...@@ -197,6 +202,20 @@ func GetBackedHas(ds Datastore, key Key) (bool, error) { ...@@ -197,6 +202,20 @@ func GetBackedHas(ds Datastore, key Key) (bool, error) {
} }
} }
// GetBackedSize provides a default Datastore.GetSize implementation.
// It exists so Datastore.GetSize implementations can use it, like so:
//
// func (*d SomeDatastore) GetSize(key Key) (size int, err error) {
// return GetBackedSize(d, key)
// }
func GetBackedSize(ds Datastore, key Key) (int, error) {
value, err := ds.Get(key)
if err == nil {
return len(value), nil
}
return -1, err
}
type Batch interface { type Batch interface {
Put(key Key, val []byte) error Put(key Key, val []byte) error
......
...@@ -33,6 +33,11 @@ func (dds *delayed) Has(key ds.Key) (exists bool, err error) { ...@@ -33,6 +33,11 @@ func (dds *delayed) Has(key ds.Key) (exists bool, err error) {
return dds.ds.Has(key) return dds.ds.Has(key)
} }
func (dds *delayed) GetSize(key ds.Key) (size int, err error) {
dds.delay.Wait()
return dds.ds.GetSize(key)
}
func (dds *delayed) Delete(key ds.Key) (err error) { func (dds *delayed) Delete(key ds.Key) (err error) {
dds.delay.Wait() dds.delay.Wait()
return dds.ds.Delete(key) return dds.ds.Delete(key)
......
...@@ -78,6 +78,10 @@ func (d *Datastore) Has(key ds.Key) (exists bool, err error) { ...@@ -78,6 +78,10 @@ func (d *Datastore) Has(key ds.Key) (exists bool, err error) {
return ds.GetBackedHas(d, key) return ds.GetBackedHas(d, key)
} }
func (d *Datastore) GetSize(key ds.Key) (size int, err error) {
return ds.GetBackedSize(d, key)
}
// Delete removes the value for given key // Delete removes the value for given key
func (d *Datastore) Delete(key ds.Key) (err error) { func (d *Datastore) Delete(key ds.Key) (err error) {
fn := d.KeyFilename(key) fn := d.KeyFilename(key)
......
...@@ -56,6 +56,16 @@ func (d *Failstore) Has(k ds.Key) (bool, error) { ...@@ -56,6 +56,16 @@ func (d *Failstore) Has(k ds.Key) (bool, error) {
return d.child.Has(k) return d.child.Has(k)
} }
// GetSize returns the size of the value in the datastore, if present.
func (d *Failstore) GetSize(k ds.Key) (int, error) {
err := d.errfunc("getsize")
if err != nil {
return -1, err
}
return d.child.GetSize(k)
}
// Delete removes a key/value from the datastore. // Delete removes a key/value from the datastore.
func (d *Failstore) Delete(k ds.Key) error { func (d *Failstore) Delete(k ds.Key) error {
err := d.errfunc("delete") err := d.errfunc("delete")
......
...@@ -48,6 +48,12 @@ func (d *ktds) Has(key ds.Key) (exists bool, err error) { ...@@ -48,6 +48,12 @@ func (d *ktds) Has(key ds.Key) (exists bool, err error) {
return d.child.Has(d.ConvertKey(key)) return d.child.Has(d.ConvertKey(key))
} }
// GetSize returns the size of the value named by the given key, transforming
// the key first.
func (d *ktds) GetSize(key ds.Key) (size int, err error) {
return d.child.GetSize(d.ConvertKey(key))
}
// Delete removes the value for given key // Delete removes the value for given key
func (d *ktds) Delete(key ds.Key) (err error) { func (d *ktds) Delete(key ds.Key) (err error) {
return d.child.Delete(d.ConvertKey(key)) return d.child.Delete(d.ConvertKey(key))
......
...@@ -106,6 +106,14 @@ func (d *Datastore) Has(key ds.Key) (exists bool, err error) { ...@@ -106,6 +106,14 @@ func (d *Datastore) Has(key ds.Key) (exists bool, err error) {
return cds.Has(k) return cds.Has(k)
} }
func (d *Datastore) GetSize(key ds.Key) (size int, err error) {
cds, _, k := d.lookup(key)
if cds == nil {
return -1, ds.ErrNotFound
}
return cds.GetSize(k)
}
func (d *Datastore) Delete(key ds.Key) error { func (d *Datastore) Delete(key ds.Key) error {
cds, _, k := d.lookup(key) cds, _, k := d.lookup(key)
if cds == nil { if cds == nil {
......
...@@ -37,6 +37,6 @@ ...@@ -37,6 +37,6 @@
"license": "MIT", "license": "MIT",
"name": "go-datastore", "name": "go-datastore",
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"", "releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
"version": "3.3.0" "version": "3.4.0"
} }
...@@ -83,3 +83,14 @@ func (d *Datastore) Has(k ds.Key) (bool, error) { ...@@ -83,3 +83,14 @@ func (d *Datastore) Has(k ds.Key) (bool, error) {
}) })
return has, err return has, err
} }
// GetSize returns the size of the value in the datastore, if present.
func (d *Datastore) GetSize(k ds.Key) (int, error) {
var size int
err := d.runOp(func() error {
var err error
size, err = d.Batching.GetSize(k)
return err
})
return size, err
}
...@@ -51,6 +51,13 @@ func (d *MutexDatastore) Has(key ds.Key) (exists bool, err error) { ...@@ -51,6 +51,13 @@ func (d *MutexDatastore) Has(key ds.Key) (exists bool, err error) {
return d.child.Has(key) return d.child.Has(key)
} }
// GetSize implements Datastore.GetSize
func (d *MutexDatastore) GetSize(key ds.Key) (size int, err error) {
d.RLock()
defer d.RUnlock()
return d.child.GetSize(key)
}
// Delete implements Datastore.Delete // Delete implements Datastore.Delete
func (d *MutexDatastore) Delete(key ds.Key) (err error) { func (d *MutexDatastore) Delete(key ds.Key) (err error) {
d.Lock() d.Lock()
......
...@@ -29,6 +29,14 @@ func SubtestBasicPutGet(t *testing.T, ds dstore.Datastore) { ...@@ -29,6 +29,14 @@ func SubtestBasicPutGet(t *testing.T, ds dstore.Datastore) {
t.Fatal("should have key foo, has returned false") t.Fatal("should have key foo, has returned false")
} }
size, err := ds.GetSize(k)
if err != nil {
t.Fatal("error getting size after put: ", err)
}
if size != len(val) {
t.Fatalf("incorrect size: expected %d, got %d", len(val), size)
}
out, err := ds.Get(k) out, err := ds.Get(k)
if err != nil { if err != nil {
t.Fatal("error getting value after put: ", err) t.Fatal("error getting value after put: ", err)
...@@ -47,6 +55,14 @@ func SubtestBasicPutGet(t *testing.T, ds dstore.Datastore) { ...@@ -47,6 +55,14 @@ func SubtestBasicPutGet(t *testing.T, ds dstore.Datastore) {
t.Fatal("should have key foo, has returned false") t.Fatal("should have key foo, has returned false")
} }
size, err = ds.GetSize(k)
if err != nil {
t.Fatal("error getting size after get: ", err)
}
if size != len(val) {
t.Fatalf("incorrect size: expected %d, got %d", len(val), size)
}
err = ds.Delete(k) err = ds.Delete(k)
if err != nil { if err != nil {
t.Fatal("error calling delete: ", err) t.Fatal("error calling delete: ", err)
...@@ -60,6 +76,18 @@ func SubtestBasicPutGet(t *testing.T, ds dstore.Datastore) { ...@@ -60,6 +76,18 @@ func SubtestBasicPutGet(t *testing.T, ds dstore.Datastore) {
if have { if have {
t.Fatal("should not have key foo, has returned true") t.Fatal("should not have key foo, has returned true")
} }
size, err = ds.GetSize(k)
switch err {
case dstore.ErrNotFound:
case nil:
t.Fatal("expected error getting size after delete")
default:
t.Fatal("wrong error getting size after delete: ", err)
}
if size != -1 {
t.Fatal("expected missing size to be -1")
}
} }
func SubtestNotFounds(t *testing.T, ds dstore.Datastore) { func SubtestNotFounds(t *testing.T, ds dstore.Datastore) {
...@@ -81,6 +109,18 @@ func SubtestNotFounds(t *testing.T, ds dstore.Datastore) { ...@@ -81,6 +109,18 @@ func SubtestNotFounds(t *testing.T, ds dstore.Datastore) {
if have { if have {
t.Fatal("has returned true for key we don't have") t.Fatal("has returned true for key we don't have")
} }
size, err := ds.GetSize(badk)
switch err {
case dstore.ErrNotFound:
case nil:
t.Fatal("expected error getting size after delete")
default:
t.Fatal("wrong error getting size after delete: ", err)
}
if size != -1 {
t.Fatal("expected missing size to be -1")
}
} }
func SubtestManyKeysAndQuery(t *testing.T, ds dstore.Datastore) { func SubtestManyKeysAndQuery(t *testing.T, ds dstore.Datastore) {
......
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