Example #1
0
// 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
}
Example #2
0
// 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
}
Example #3
0
// 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
}