func (self *clientWithPrefix) ListRemove(kv *trib.KeyValue, n *int) error { // escape colon binName := colon.Escape(self.bin) kv.Key = colon.Escape(kv.Key) kv.Key = binName + "::" + kv.Key // RPC call return self.originalClient.ListRemove(kv, n) }
func (self *clientWithPrefix) ListAppend(kv *trib.KeyValue, succ *bool) error { // escape colon binName := colon.Escape(self.bin) kv.Key = colon.Escape(kv.Key) kv.Key = binName + "::" + kv.Key // RPC call return self.originalClient.ListAppend(kv, succ) }
func (self *clientWithPrefix) ListGet(key string, list *trib.List) error { // escape colon binName := colon.Escape(self.bin) key = colon.Escape(key) key = binName + "::" + key // RPC call return self.originalClient.ListGet(key, list) }
func (self *clientWithPrefix) Get(key string, value *string) error { // escape colon binName := colon.Escape(self.bin) key = colon.Escape(key) key = binName + "::" + key // RPC call return self.originalClient.Get(key, value) }
func (self *ReplicaClient) ListAppend(kv *trib.KeyValue, succ *bool) error { var clk uint64 *succ = true err1 := self.Clock(0, &clk) if err1 != nil { return err1 } var newkv trib.KeyValue newkv.Key = colon.Escape(self.name) + "::" + kv.Key + "list" log := BinLog{"append", kv.Value, clk} newkv.Value = EncodeLog(log) success := false for _, ad := range self.addr { tempclient := &client{ad} var b bool err2 := tempclient.ListAppend(&newkv, &b) if err2 == nil { success = true } } if success == true { return nil } else { return fmt.Errorf("ListAppend failure on all servers") } }
func (self *clientWithPrefix) ListKeys(p *trib.Pattern, list *trib.List) error { // escape colon binName := colon.Escape(self.bin) p.Prefix = binName + "::" + colon.Escape(p.Prefix) p.Suffix = colon.Escape(p.Suffix) // RPC call err := self.originalClient.ListKeys(p, list) if err != nil { return err } // unescape and trim for i, str := range list.L { str = colon.Unescape(str) list.L[i] = strings.TrimPrefix(str, self.bin+"::") } return nil }
func replicateHelper(srcAddr, dstAddr, binName string) error { srcClient := NewClient(srcAddr) dstClient := NewClient(dstAddr) pt := trib.Pattern{Prefix: colon.Escape(binName) + "::", Suffix: ""} keyList := new(trib.List) // migrate key-value pairs err := srcClient.Keys(&pt, keyList) if err != nil { return err } var tmpVal string var succ bool for _, key := range keyList.L { err = srcClient.Get(key, &tmpVal) if err != nil { return err } err = dstClient.Set(&trib.KeyValue{Key: key, Value: tmpVal}, &succ) if err != nil || !succ { return fmt.Errorf("Set() fails when migrating") } } // migrate key-list pairs err = srcClient.ListKeys(&pt, keyList) if err != nil { return err } var valList trib.List for _, key := range keyList.L { err = srcClient.ListGet(key, &valList) if err != nil { return err } for _, val := range valList.L { err = dstClient.ListAppend(&trib.KeyValue{Key: key, Value: val}, &succ) if err != nil || !succ { return fmt.Errorf("ListAppend() fails when migrating") } } } return nil }
func (self *ReplicaClient) Get(key string, value *string) error { newkey := colon.Escape(self.name) + "::" + key + "valu" // <- key should escape as well! NVM var mylist trib.List mylist.L = make([]string, 0) // get the list of logs of the key for index, ad := range self.addr { tempclient := &client{ad} err1 := tempclient.ListGet(newkey, &mylist) if err1 == nil { break } else if index < len(self.addr)-1 { continue } else { return err1 } } s := "" if len(mylist.L) == 0 { *value = s return nil } // add dedup mylist.L = removeDuplicates(mylist.L) loglist := make(LogSlice, len(mylist.L)) // decode the logs for index, l := range mylist.L { loglist[index] = DecodeLog(l) } sort.Sort(loglist) index := len(loglist) - 1 result := loglist[index].Val *value = result return nil }
func (self *ReplicaClient) ListRemove(kv *trib.KeyValue, n *int) error { var clk uint64 err1 := self.Clock(0, &clk) if err1 != nil { return err1 } var tempList trib.List self.ListGet(kv.Key, &tempList) r := 0 for _, element := range tempList.L { if element == kv.Value { r++ } } *n = r var newkv trib.KeyValue newkv.Key = colon.Escape(self.name) + "::" + kv.Key + "list" log := BinLog{"remove", kv.Value, clk} newkv.Value = EncodeLog(log) success := false for _, ad := range self.addr { tempclient := &client{ad} var b bool err2 := tempclient.ListAppend(&newkv, &b) if err2 == nil { success = true } } if success == true { return nil } else { return fmt.Errorf("ListRemove failure on all servers") } }
func (self *ReplicaClient) ListKeys(p *trib.Pattern, list *trib.List) error { // escape colon binName := colon.Escape(self.name) p.Prefix = binName + "::" + p.Prefix p.Suffix = p.Suffix + "list" // RPC call // get the list of logs of the key // a list used as temp storage tmpList := trib.List{make([]string, 0)} for index, ad := range self.addr { tempclient := &client{ad} err1 := tempclient.ListKeys(p, &tmpList) if err1 == nil { break } else if index < len(self.addr)-1 { continue } else { return err1 } } blockCh := make(chan string, len(tmpList.L)) for _, str := range tmpList.L { go func(str string) { tmpList2 := trib.List{make([]string, 0)} s1 := colon.Escape(self.name) + "::" s2 := "list" str = strings.TrimPrefix(str, s1) str = strings.TrimSuffix(str, s2) _ = self.ListGet(str, &tmpList2) // ignore this err? if len(tmpList2.L) != 0 { blockCh <- str } else { blockCh <- "" } }(str) } list.L = make([]string, 0, len(tmpList.L)) for _ = range tmpList.L { result := <-blockCh if result != "" { list.L = append(list.L, result) } } // unescape and trim if len(list.L) > 0 { for i, str := range list.L { //str = colon.Unescape(str) s1 := colon.Escape(self.name) + "::" s2 := "valu" str = strings.TrimPrefix(str, s1) str = strings.TrimSuffix(str, s2) list.L[i] = str } } return nil }
func (self *ReplicaClient) ListGet(key string, list *trib.List) error { newkey := colon.Escape(self.name) + "::" + key + "list" var mylist trib.List mylist.L = make([]string, 0) // get the list of logs of the key for index, ad := range self.addr { tempclient := &client{ad} err1 := tempclient.ListGet(newkey, &mylist) if err1 == nil { break } else if index < len(self.addr)-1 { continue } else { return err1 } } if len(mylist.L) == 0 { list.L = make([]string, 0) return nil } // add dedup mylist.L = removeDuplicates(mylist.L) loglist := make(LogSlice, len(mylist.L)) // decode the logs for index, l := range mylist.L { loglist[index] = DecodeLog(l) } sort.Sort(loglist) var templist trib.List //get the real list for _, log := range loglist { if log.Op == "append" { templist.L = append(templist.L, log.Val) } else { // remove? newList := trib.List{[]string{}} for _, entry := range templist.L { if log.Val != entry { newList.L = append(newList.L, entry) } } templist.L = newList.L /*i := 0 for _, l := range templist.L{ if l == log.Val { if i < len(templist.L) { templist.L = append(templist.L[:i], templist.L[i+1:]...) } else { templist.L = templist.L[:i] } } else { i++ } }*/ } } *list = templist return nil }