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) {
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
func (d *Datastore) Query(q dsq.Query) (dsq.Results, error) {
err := d.Flush()
......
......@@ -42,6 +42,14 @@ func (d *MapDatastore) Has(key Key) (exists bool, err error) {
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
func (d *MapDatastore) Delete(key Key) (err error) {
if _, found := d.values[key]; !found {
......@@ -95,6 +103,11 @@ func (d *NullDatastore) Has(key Key) (exists bool, err error) {
return false, nil
}
// Has implements Datastore.GetSize
func (d *NullDatastore) GetSize(key Key) (size int, err error) {
return -1, ErrNotFound
}
// Delete implements Datastore.Delete
func (d *NullDatastore) Delete(key Key) (err error) {
return nil
......@@ -158,6 +171,12 @@ func (d *LogDatastore) Has(key Key) (exists bool, err error) {
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
func (d *LogDatastore) Delete(key Key) (err error) {
log.Printf("%s: Delete %s\n", d.Name, key)
......
......@@ -52,6 +52,11 @@ type Datastore interface {
// The default implementation is found in `GetBackedHas`.
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(key Key) 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 {
Put(key Key, val []byte) error
......
......@@ -33,6 +33,11 @@ func (dds *delayed) Has(key ds.Key) (exists bool, err error) {
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) {
dds.delay.Wait()
return dds.ds.Delete(key)
......
......@@ -78,6 +78,10 @@ func (d *Datastore) Has(key ds.Key) (exists bool, err error) {
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
func (d *Datastore) Delete(key ds.Key) (err error) {
fn := d.KeyFilename(key)
......
......@@ -56,6 +56,16 @@ func (d *Failstore) Has(k ds.Key) (bool, error) {
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.
func (d *Failstore) Delete(k ds.Key) error {
err := d.errfunc("delete")
......
......@@ -48,6 +48,12 @@ func (d *ktds) Has(key ds.Key) (exists bool, err error) {
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
func (d *ktds) Delete(key ds.Key) (err error) {
return d.child.Delete(d.ConvertKey(key))
......
......@@ -106,6 +106,14 @@ func (d *Datastore) Has(key ds.Key) (exists bool, err error) {
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 {
cds, _, k := d.lookup(key)
if cds == nil {
......
......@@ -37,6 +37,6 @@
"license": "MIT",
"name": "go-datastore",
"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) {
})
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) {
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
func (d *MutexDatastore) Delete(key ds.Key) (err error) {
d.Lock()
......
......@@ -29,6 +29,14 @@ func SubtestBasicPutGet(t *testing.T, ds dstore.Datastore) {
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)
if err != nil {
t.Fatal("error getting value after put: ", err)
......@@ -47,6 +55,14 @@ func SubtestBasicPutGet(t *testing.T, ds dstore.Datastore) {
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)
if err != nil {
t.Fatal("error calling delete: ", err)
......@@ -60,6 +76,18 @@ func SubtestBasicPutGet(t *testing.T, ds dstore.Datastore) {
if have {
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) {
......@@ -81,6 +109,18 @@ func SubtestNotFounds(t *testing.T, ds dstore.Datastore) {
if 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) {
......
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