// Delete removes a value with given key. func (db *LevelDB) Delete(ctx storage.Context, tk storage.TKey) error { if db == nil { return fmt.Errorf("Can't call Delete on nil LevelDB") } if ctx == nil { return fmt.Errorf("Received nil context in Delete()") } wo := db.options.WriteOptions var err error key := ctx.ConstructKey(tk) if !ctx.Versioned() { dvid.StartCgo() err = db.ldb.Delete(wo, key) dvid.StopCgo() } else { vctx, ok := ctx.(storage.VersionedCtx) if !ok { return fmt.Errorf("Non-versioned context that says it's versioned received in Delete(): %v", ctx) } tombstoneKey := vctx.TombstoneKey(tk) batch := db.NewBatch(vctx).(*goBatch) batch.WriteBatch.Delete(key) batch.WriteBatch.Put(tombstoneKey, dvid.EmptyValue()) if err = batch.Commit(); err != nil { dvid.Criticalf("Error on batch commit of Delete: %v\n", err) err = fmt.Errorf("Error on batch commit of Delete: %v", err) } } return err }
// Put writes a value with given key. func (db *LevelDB) Put(ctx storage.Context, tk storage.TKey, v []byte) error { if ctx == nil { return fmt.Errorf("Received nil context in Put()") } wo := db.options.WriteOptions var err error key := ctx.ConstructKey(tk) if !ctx.Versioned() { dvid.StartCgo() err = db.ldb.Put(wo, key, v) dvid.StopCgo() } else { vctx, ok := ctx.(storage.VersionedCtx) if !ok { return fmt.Errorf("Non-versioned context that says it's versioned received in Put(): %v", ctx) } tombstoneKey := vctx.TombstoneKey(tk) batch := db.NewBatch(vctx).(*goBatch) batch.WriteBatch.Delete(tombstoneKey) batch.WriteBatch.Put(key, v) if err = batch.Commit(); err != nil { batch.Close() err = fmt.Errorf("Error on PUT: %v\n", err) } } storage.StoreKeyBytesWritten <- len(key) storage.StoreValueBytesWritten <- len(v) return err }
// Delete removes a value with given key. func (db *KVAutobus) Delete(ctx storage.Context, tk storage.TKey) error { if ctx == nil { return fmt.Errorf("Received nil context in Delete()") } key := ctx.ConstructKey(tk) return db.RawDelete(key) }
// Get returns a value given a key. func (db *LevelDB) Get(ctx storage.Context, tk storage.TKey) ([]byte, error) { if ctx == nil { return nil, fmt.Errorf("Received nil context in Get()") } if ctx.Versioned() { vctx, ok := ctx.(storage.VersionedCtx) if !ok { return nil, fmt.Errorf("Bad Get(): context is versioned but doesn't fulfill interface: %v", ctx) } // Get all versions of this key and return the most recent // log.Printf(" basholeveldb versioned get of key %v\n", k) values, err := db.getSingleKeyVersions(vctx, tk) // log.Printf(" got back %v\n", values) if err != nil { return nil, err } kv, err := vctx.VersionedKeyValue(values) // log.Printf(" after deversioning: %v\n", kv) if kv != nil { return kv.V, err } return nil, err } else { key := ctx.ConstructKey(tk) ro := db.options.ReadOptions // log.Printf(" basholeveldb unversioned get of key %v\n", key) dvid.StartCgo() v, err := db.ldb.Get(ro, key) dvid.StopCgo() storage.StoreValueBytesRead <- len(v) return v, err } }
// Get returns a value given a key. func (db *KVAutobus) Get(ctx storage.Context, tk storage.TKey) ([]byte, error) { if ctx == nil { return nil, fmt.Errorf("Received nil context in Get()") } if ctx.Versioned() { vctx, ok := ctx.(storage.VersionedCtx) if !ok { return nil, fmt.Errorf("Bad Get(): context is versioned but doesn't fulfill interface: %v", ctx) } // Get all versions of this key and return the most recent // log.Printf(" kvautobus versioned get of key %v\n", k) key := ctx.ConstructKey(tk) dvid.Infof(" Get on key: %s\n", hex.EncodeToString(key)) values, err := db.getSingleKeyVersions(vctx, tk) // log.Printf(" got back %v\n", values) if err != nil { return nil, err } kv, err := vctx.VersionedKeyValue(values) // log.Printf(" after deversioning: %v\n", kv) if kv != nil { return kv.V, err } return nil, err } else { key := ctx.ConstructKey(tk) // log.Printf(" kvautobus unversioned get of key %v\n", key) v, err := db.RawGet(key) storage.StoreValueBytesRead <- len(v) return v, err } }
// GetTileKey returns the internal key as a hexadecimal string func (d *Data) GetTileKey(ctx storage.Context, w http.ResponseWriter, r *http.Request, parts []string) (string, error) { req, err := d.ParseTileReq(r, parts) if err != nil { return "", err } tk := NewTKeyByTileReq(req) key := ctx.ConstructKey(tk) return fmt.Sprintf("%x", key), nil }
// PutRange puts type key-value pairs that have been sorted in sequential key order. func (db *KVAutobus) PutRange(ctx storage.Context, tkvs []storage.TKeyValue) error { if ctx == nil { return fmt.Errorf("Received nil context in PutRange()") } kvs := make([]storage.KeyValue, len(tkvs)) for i, tkv := range tkvs { kvs[i] = storage.KeyValue{ctx.ConstructKey(tkv.K), tkv.V} } return db.putRange(kvs) }
// DeleteRange removes all key-value pairs with keys in the given range. Versioned // contexts cannot use immutable stores to delete ranges. func (db *KVAutobus) DeleteRange(ctx storage.Context, kStart, kEnd storage.TKey) error { if ctx == nil { return fmt.Errorf("Received nil context in DeleteRange()") } if ctx.Versioned() { return fmt.Errorf("DeleteRange() not supported for versioned contexts in immutable store") } keyBeg := ctx.ConstructKey(kStart) keyEnd := ctx.ConstructKey(kEnd) return db.deleteRange(keyBeg, keyEnd) }
// Put writes a value with given key. Since KVAutobus is immutable, we do not // have to worry about a PUT on a previously deleted key. func (db *KVAutobus) Put(ctx storage.Context, tk storage.TKey, v []byte) error { if ctx == nil { return fmt.Errorf("Received nil context in Put()") } key := ctx.ConstructKey(tk) err := db.RawPut(key, v) if err != nil { return err } return nil }
// unversionedRange sends a range of key-value pairs down a channel. func (db *LevelDB) unversionedRange(ctx storage.Context, begTKey, endTKey storage.TKey, ch chan errorableKV, done <-chan struct{}, keysOnly bool) { dvid.StartCgo() ro := levigo.NewReadOptions() it := db.ldb.NewIterator(ro) defer func() { it.Close() dvid.StopCgo() }() // Apply context if applicable begKey := ctx.ConstructKey(begTKey) endKey := ctx.ConstructKey(endTKey) // fmt.Printf("unversionedRange():\n") // fmt.Printf(" index beg: %v\n", kStart) // fmt.Printf(" index end: %v\n", kEnd) // fmt.Printf(" key start: %v\n", keyBeg) // fmt.Printf(" key end: %v\n", keyEnd) var itValue []byte it.Seek(begKey) for { if it.Valid() { // fmt.Printf("unversioned found key %v, %d bytes value\n", it.Key(), len(it.Value())) if !keysOnly { itValue = it.Value() storage.StoreValueBytesRead <- len(itValue) } itKey := it.Key() storage.StoreKeyBytesRead <- len(itKey) // Did we pass the final key? if bytes.Compare(itKey, endKey) > 0 { break } select { case <-done: ch <- errorableKV{nil, nil} return case ch <- errorableKV{&storage.KeyValue{K: itKey, V: itValue}, nil}: it.Next() } } else { break } } if err := it.GetError(); err != nil { ch <- errorableKV{nil, err} } else { ch <- errorableKV{nil, nil} } return }
// unversionedRange sends a range of key-value pairs down a channel. func (db *KVAutobus) unversionedRange(ctx storage.Context, kStart, kEnd storage.TKey, ch chan errorableKV, keysOnly bool) { keyBeg := ctx.ConstructKey(kStart) keyEnd := ctx.ConstructKey(kEnd) kvs, err := db.getRange(ctx, keyBeg, keyEnd) if err != nil { ch <- errorableKV{nil, err} } for _, kv := range kvs { ch <- errorableKV{kv, nil} } ch <- errorableKV{nil, nil} }
// Put writes a value with given key. Since KVAutobus is immutable, we do not // have to worry about a PUT on a previously deleted key. func (db *KVAutobus) Put(ctx storage.Context, tk storage.TKey, v []byte) error { if ctx == nil { return fmt.Errorf("Received nil context in Put()") } key := ctx.ConstructKey(tk) err := db.RawPut(key, v) if err != nil { return err } storage.StoreKeyBytesWritten <- len(key) storage.StoreValueBytesWritten <- len(v) return nil }
// unversionedRange sends a range of key-value pairs down a channel. func (db *KVAutobus) unversionedRange(ctx storage.Context, kStart, kEnd storage.TKey, ch chan errorableKV, keysOnly bool) { keyBeg := ctx.ConstructKey(kStart) keyEnd := ctx.ConstructKey(kEnd) kvs, err := db.getRange(keyBeg, keyEnd) if err != nil { ch <- errorableKV{nil, err} } for _, kv := range kvs { if !keysOnly { storage.StoreValueBytesRead <- len(kv.V) } storage.StoreKeyBytesRead <- len(kv.K) ch <- errorableKV{kv, nil} } ch <- errorableKV{nil, nil} return }