// RawDelete is a low-level function. It deletes a key-value pair using full keys // without any context. This can be used in conjunction with RawRangeQuery. func (db *BigTable) RawDelete(fullKey storage.Key) error { if db == nil { return fmt.Errorf("Can't call RawDelete() on nil BigTable") } unvKey, verKey, err := storage.SplitKey(fullKey) if err != nil { return fmt.Errorf("Error in RawDelete(): %v\n", err) } r, err := tbl.ReadRow(db.ctx, encodeKey(unvKey), api.RowFilter(api.StripValueFilter())) //A missing row will return a zero-length map and a nil error if len(r) == 0 { return fmt.Errorf("Error in RawDelete(): This unvKey doesn't exists") } if err != nil { return err } if len(r[familyName]) == 0 { return fmt.Errorf("Error in Delete(): This row is empty") } _, err = getValue(r, verKey) if err != nil { return fmt.Errorf("Error in Delete(): The version to be deleted doesn't exist") } mut := api.NewMutation() //There is only one version left, and is the one we are trying to delete\ //remove the whole row if len(r[familyName]) == 1 { mut.DeleteRow() } else { mut.DeleteCellsInColumn(familyName, encodeKey(verKey)) } err = tbl.Apply(db.ctx, encodeKey(unvKey), mut) if err != nil { return fmt.Errorf("Error in Delete(): %v\n", err) } return err }
// RawPut is a low-level function that puts a key-value pair using full keys. // This can be used in conjunction with RawRangeQuery. func (db *BigTable) RawPut(fullKey storage.Key, value []byte) error { if db == nil { return fmt.Errorf("Can't call RawPut() on nil BigTable") } unvKey, verKey, err := storage.SplitKey(fullKey) if err != nil { return fmt.Errorf("Error in RawPut(): %v\n", err) } mut := api.NewMutation() mut.Set(familyName, encodeKey(verKey), 0, value) err = tbl.Apply(db.ctx, encodeKey(unvKey), mut) if err != nil { return fmt.Errorf("Error in RawPut(): %v\n", err) } return err }
// RawRangeQuery sends a range of full keys. This is to be used for low-level data // retrieval like DVID-to-DVID communication and should not be used by data type // implementations if possible because each version's key-value pairs are sent // without filtering by the current version and its ancestor graph. A nil is sent // down the channel when the range is complete. func (db *BigTable) RawRangeQuery(kStart, kEnd storage.Key, keysOnly bool, out chan *storage.KeyValue, cancel <-chan struct{}) error { if db == nil { return fmt.Errorf("Can't call RawRangeQuery() on nil BigTable") } unvKeyBeg, verKeyBeg, err := storage.SplitKey(kStart) if err != nil { dvid.Errorf("Error in RawRangeQuery(): %v\n", err) return err } unvKeyEnd, verKeyEnd, err := storage.SplitKey(kEnd) if err != nil { dvid.Errorf("Error in RawRangeQuery(): %v\n", err) return err } rr := api.NewRange(encodeKey(unvKeyBeg), encodeKey(unvKeyEnd)) err = tbl.ReadRows(db.ctx, rr, func(r api.Row) bool { if cancel != nil { select { case <-cancel: out <- nil return nil default: } } unvKeyRow, err := decodeKey(r.Key()) if err != nil { dvid.Errorf("Error in RawRangeQuery(): %v\n", err) return false } //I need the versioned key to merged it with the unversioned // and send it throu the channel for _, readItem := range r[familyName] { verKey, err := decodeKey(readItem.Column) if err != nil { dvid.Errorf("Error in RawRangeQuery(): %v\n", err) return false } lowerLimit := bytes.Equal(unvKeyBeg, unvKeyRow) && bytes.Compare(verKey, verKeyBeg) == -1 upperLimit := bytes.Equal(unvKeyEnd, unvKeyRow) && bytes.Compare(verKey, verKeyEnd) >= 0 if lowerLimit || upperLimit { continue } fullKey := storage.MergeKey(unvKeyRow, verKey) kv := storage.KeyValue{fullKey, readItem.Value} out <- &kv } return true // keep going }) return nil }