func (self *TX) setOp(expr *setop.SetExpression) (result []kv) { if err := expr.Each(self.skipper, func(res *setop.SetOpResult) { result = append(result, kv{ Keys: [][]byte{res.Key}, Value: res.Values[0], }) }); err != nil { panic(err) } return }
// SetExpression will execute the given expr. // // If expr.Dest is set it will store the result under the sub tree defined by expr.Dest. // // If expr.Dest is nil it will return the result. // // Either expr.Op or expr.Code has to be set. // // If expr.Op is nil expr.Code will be parsed using SetOpParser to provide expr.Op. func (self *Conn) SetExpression(expr setop.SetExpression) (result []setop.SetOpResult) { if expr.Op == nil { expr.Op = setop.MustParse(expr.Code) } var biggestKey []byte biggestSize := 0 var thisSize int for key, _ := range findKeys(expr.Op) { thisSize = self.SubSize([]byte(key)) if biggestKey == nil { biggestKey = []byte(key) biggestSize = thisSize } else if thisSize > biggestSize { biggestKey = []byte(key) biggestSize = thisSize } } _, _, successor := self.ring.Remotes(biggestKey) var results []setop.SetOpResult err := successor.Call("DHash.SetExpression", expr, &results) for err != nil { self.removeNode(*successor) _, _, successor = self.ring.Remotes(biggestKey) err = successor.Call("DHash.SetExpression", expr, &results) } return results }
func (self *Node) SetExpression(expr setop.SetExpression, items *[]setop.SetOpResult) (err error) { if expr.Dest != nil { if expr.Op.Merge == setop.Append { err = fmt.Errorf("When storing results of Set expressions the Append merge function is not allowed") return } successor := self.node.GetSuccessorFor(expr.Dest) if successor.Addr != self.node.GetBroadcastAddr() { return successor.Call("DHash.SetExpression", expr, items) } } data := common.Item{ Key: expr.Dest, } err = expr.Each(func(b []byte) (result setop.Skipper, err error) { succ := self.node.GetSuccessorFor(b) res := &treeSkipper{ remote: succ, key: b, } if succ.Addr == self.node.GetBroadcastAddr() { res.tree = self.tree } result = res return }, func(res *setop.SetOpResult) { if expr.Dest == nil { *items = append(*items, *res) } else { data.SubKey = res.Key data.Value = res.Values[0] data.TTL = self.node.Redundancy() data.Timestamp = self.timer.ContinuousTime() self.subPut(data) } }) return }