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 *client) ListGet(key string, list *trib.List) error { // connect to the server conn, e := rpc.DialHTTP("tcp", self.addr) if e != nil { return e } // perform the call list.L = nil e = conn.Call("Storage.ListGet", key, list) if e != nil { conn.Close() return e } if list.L == nil { list.L = []string{} } // close the connection return conn.Close() }
func (self *Storage) ListGet(key string, ret *trib.List) error { self.listLock.Lock() defer self.listLock.Unlock() if lst, found := self.lists[key]; !found { ret.L = []string{} } else { ret.L = make([]string, 0, lst.Len()) for i := lst.Front(); i != nil; i = i.Next() { ret.L = append(ret.L, i.Value.(string)) } } if Logging { log.Printf("ListGet(%q) => %d", key, len(ret.L)) for i, s := range ret.L { log.Printf(" %d: %q", i, s) } } return nil }
func (self *FrontServer) Following(who string) ([]string, error) { _, e := self.findUser(who) if e != nil { return nil, e } client := self.storageClient.Bin(who) followingUsers := trib.List{L: []string{}} if e := client.ListGet("Followings", &followingUsers); e != nil { return nil, e } followingUsers.L = removeDuplicates(followingUsers.L) return followingUsers.L, nil }
func (self *Storage) ListKeys(p *trib.Pattern, r *trib.List) error { self.listLock.Lock() defer self.listLock.Unlock() ret := make([]string, 0, len(self.lists)) for k := range self.lists { if p.Match(k) { ret = append(ret, k) } } r.L = ret if Logging { log.Printf("ListKeys(%q, %q) => %d", p.Prefix, p.Suffix, len(r.L)) for i, s := range r.L { log.Printf(" %d: %q", i, s) } } return nil }
func (self *FrontServer) Home(user string) ([]*trib.Trib, error) { self.lock.Lock() defer self.lock.Unlock() _, e := self.findUser(user) if e != nil { return nil, e } followingUsers, e := self.Following(user) if e != nil { return nil, e } followingUsers = append(followingUsers, user) wholeRawList := trib.List{L: []string{}} for _, followed := range followingUsers { client := self.storageClient.Bin(followed) rawList := trib.List{L: []string{}} if e := client.ListGet("Tribs", &rawList); e != nil { return nil, e } wholeRawList.L = append(wholeRawList.L, rawList.L...) } size := len(wholeRawList.L) tribList := make([]*trib.Trib, size) for i, entry := range wholeRawList.L { if e := json.Unmarshal([]byte(entry), &tribList[i]); e != nil { return nil, e } } // sort by logic clock sort.Sort(byClock(tribList)) l := len(tribList) start := 0 if l > trib.MaxTribFetch { start = l - trib.MaxTribFetch } return tribList[start:], nil }
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 }