// 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 testSetExpression(t *testing.T, c testClient) { t1 := []byte("sete1") t2 := []byte("sete2") for i := byte(0); i < 10; i++ { c.SubPut(t1, []byte{i}, common.EncodeBigInt(big.NewInt(1))) } for i := byte(5); i < 15; i++ { c.SubPut(t2, []byte{i}, common.EncodeBigInt(big.NewInt(1))) } assertSetOps(t, c.SetExpression(setop.SetExpression{ Op: setop.MustParse("(U:BigIntAnd sete1 sete2)"), }), []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}) assertSetOps(t, c.SetExpression(setop.SetExpression{ Min: []byte{2}, Max: []byte{6}, Op: setop.MustParse("(U:BigIntAnd sete1 sete2)"), }), []byte{3, 4, 5}, []byte{1, 1, 1}) assertSetOps(t, c.SetExpression(setop.SetExpression{ Min: []byte{2}, Max: []byte{6}, MinInc: true, MaxInc: true, Op: setop.MustParse("(U:BigIntAnd sete1 sete2)"), }), []byte{2, 3, 4, 5, 6}, []byte{1, 1, 1, 1, 1}) assertSetOps(t, c.SetExpression(setop.SetExpression{ Min: []byte{2}, Max: []byte{6}, MinInc: true, MaxInc: true, Len: 3, Op: setop.MustParse("(U:BigIntAnd sete1 sete2)"), }), []byte{2, 3, 4}, []byte{1, 1, 1}) assertSetOps(t, c.SetExpression(setop.SetExpression{ Min: []byte{2}, Max: []byte{6}, MinInc: true, MaxInc: true, Len: 3, Dest: []byte("sete3"), Op: setop.MustParse("(U:BigIntAnd sete1 sete2)"), }), []byte{}, []byte{}) min := 0 max := 100 assertItems(t, c.SliceIndex([]byte("sete3"), &min, &max), []byte{2, 3, 4}, []byte{1, 1, 1}) assertSetOps(t, c.SetExpression(setop.SetExpression{ Code: "(U:BigIntAnd sete1 sete2)", }), []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}) assertSetOps(t, c.SetExpression(setop.SetExpression{ Min: []byte{2}, Max: []byte{6}, Code: "(U:BigIntAnd sete1 sete2)", }), []byte{3, 4, 5}, []byte{1, 1, 1}) assertSetOps(t, c.SetExpression(setop.SetExpression{ Min: []byte{2}, Max: []byte{6}, MinInc: true, MaxInc: true, Code: "(U:BigIntAnd sete1 sete2)", }), []byte{2, 3, 4, 5, 6}, []byte{1, 1, 1, 1, 1}) assertSetOps(t, c.SetExpression(setop.SetExpression{ Min: []byte{2}, Max: []byte{6}, MinInc: true, MaxInc: true, Len: 3, Code: "(U:BigIntAnd sete1 sete2)", }), []byte{2, 3, 4}, []byte{1, 1, 1}) assertSetOps(t, c.SetExpression(setop.SetExpression{ Min: []byte{2}, Max: []byte{6}, MinInc: true, MaxInc: true, Len: 3, Dest: []byte("sete4"), Code: "(U:BigIntAnd sete1 sete2)", }), []byte{}, []byte{}) assertItems(t, c.SliceIndex([]byte("sete4"), &min, &max), []byte{2, 3, 4}, []byte{1, 1, 1}) }