Commit 1cd3a342 authored by Steven Allen's avatar Steven Allen

add a GetSize method

We can also add this as an extension but it's simple enough I'd like to add it
directly to the Datastore.

Use-case: The blockstore now has a GetSize and bitswap uses it for packing
multiple blocks into a single message. Unfortunately, this means that bitswap is
now calling blockstore.GetSize which calls datastore.Get which tends to be more
expensive than datastore.Has.
parent 19b8f34d
...@@ -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 {
......
...@@ -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()
......
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