// Get returns *KVItem for a key. If key is not found on this node, but node holds key replica, replica is returned. // If key is not found on this node, and node does not hold replica, request is forwarded to the node responsible // for this key. *KVItem is nil if key was not found, and error is set if there was an error during request. func (q *query) Get(key []byte) (*KVItem, error) { if key == nil || len(key) == 0 { return nil, fmt.Errorf("key can not be nil or empty") } reqItem := new(kvItem) reqItem.Key = key reqItem.keyHash = dendrite.HashKey(key) item, err := q.dt.get(reqItem) if err != nil { return nil, err } if item == nil { return nil, nil } return &item.KVItem, nil }
// Set writes to dtable. func (q *query) Set(key, val []byte) error { if key == nil || len(key) == 0 { return fmt.Errorf("key can not be nil or empty") } q.qType = qSet reqItem := new(kvItem) reqItem.lock = new(sync.Mutex) reqItem.Key = make([]byte, len(key)) copy(reqItem.Key, key) if val != nil { reqItem.Val = make([]byte, len(val)) copy(reqItem.Val, val) } reqItem.keyHash = dendrite.HashKey(key) reqItem.timestamp = time.Now() reqItem.replicaInfo = new(kvReplicaInfo) reqItem.replicaInfo.vnodes = make([]*dendrite.Vnode, q.dt.ring.Replicas()) reqItem.replicaInfo.orphan_vnodes = make([]*dendrite.Vnode, 0) wait := make(chan error) succs, err := q.dt.ring.Lookup(1, reqItem.keyHash) if err != nil { return err } if len(succs) != 1 || succs[0] == nil { return fmt.Errorf("successor lookup failed for key, %x", reqItem.keyHash) } // see if this node is responsible for this key _, ok := q.dt.table[succs[0].String()] if ok { go q.dt.set(succs[0], reqItem, q.minAcks, wait) } else { // pass to remote reqItem.replicaInfo.master = succs[0] go q.dt.remoteSet(succs[0], succs[0], reqItem, q.minAcks, false, wait) } err = <-wait return err }
func (item *kvItem) keyHashString() string { if item.keyHash == nil { item.keyHash = dendrite.HashKey(item.Key) } return fmt.Sprintf("%x", item.keyHash) }