func Insert(e Elem, L *list.List) int { if L.Len() == 0 { L.PushFront(e) return L.Len() } front := L.Front() if e.GetTime() < front.Value.(Elem).GetTime() { L.InsertBefore(e, front) return L.Len() } el := L.Back() Loop: for { if el.Value.(Elem).GetTime() > e.GetTime() { el = el.Prev() } else { break Loop } } L.InsertAfter(e, el) return L.Len() }
//add Nodes we here about in the reply to the shortList, only if that node is not in the sentList func addResponseNodesToSL(fnodes []FoundNode, shortList *list.List, sentMap map[ID]bool, targetID ID) { for i := 0; i < len(fnodes); i++ { foundNode := &fnodes[i] _, inSentList := sentMap[foundNode.NodeID] //if the foundNode is already in sentList, dont add it to shortList if inSentList { continue } for e := shortList.Front(); e != nil; e = e.Next() { if e.Value.(*FoundNode).NodeID.Equals(foundNode.NodeID) { break } dist := e.Value.(*FoundNode).NodeID.Distance(targetID) foundNodeDist := foundNode.NodeID.Distance(targetID) //if responseNode is closer than node in ShortList, add it if foundNodeDist < dist { shortList.InsertBefore(foundNode, e) //keep the shortList length < Kconst if shortList.Len() > KConst { shortList.Remove(shortList.Back()) } //node inserted! getout break } } } }
func findRefKClosestTo(kadems []*Kademlia, portrange int, searchID ID, KConst int) *list.List { var retList *list.List = list.New() for i := 0; i < len(kadems); i++ { var newNodeID ID var newNodeIDDist int newNodeID = CopyID(kadems[i].ContactInfo.NodeID) newNodeIDDist = newNodeID.Distance(searchID) var e *list.Element = retList.Front() for ; e != nil; e = e.Next() { var dist int dist = e.Value.(ID).Distance(searchID) //if responseNode is closer than node in ShortList, add it if newNodeIDDist < dist { retList.InsertBefore(newNodeID, e) //node inserted! getout break } } if e == nil { //node is farthest yet retList.PushBack(newNodeID) } } return retList }
func insertByPriority(l *list.List, match *CompiledMatch) { for i := l.Front(); i != nil; i = i.Next() { cur := i.Value.(*CompiledMatch) if cur.Template.Priority <= match.Template.Priority { l.InsertBefore(match, i) return } } //either list is empty, or we're lowest priority template l.PushBack(match) }
func (pkg *archPkg) addPkgSorted(lst *list.List) { for p := lst.Front(); p != nil; p = p.Next() { ele := (p.Value).(*archPkg) if vercmp(pkg.Version, ele.Version) == "-1" { lst.InsertBefore(pkg, p) return } } lst.PushBack(pkg) }
func addPkgSorted(lst *list.List, pkg *archPkg) { for p := lst.Front(); p != nil; p = p.Next() { ele := (p.Value).(*archPkg) /* vercmp returns -1, which underflows */ if vercmp(pkg.Version, ele.Version) == 255 { lst.InsertBefore(pkg, p) return } } lst.PushBack(pkg) }
func insertUniqueBigInt(l *list.List, i *big.Int) { new := big.NewInt(0) for e := l.Front(); e != nil; e = e.Next() { switch i.Cmp(e.Value.(*big.Int)) { case -1: new.Set(i) l.InsertBefore(new, e) return case 0: return } } new.Set(i) l.PushBack(new) }
// doesn't insert contacts whose nodeID is already in the list func insertSorted(inputlist *list.List, item Contact, compare func(Contact, Contact) int) { for e := inputlist.Front(); e != nil; e = e.Next() { c := e.Value.(Contact) comp := compare(c, item) if comp == 0 { // don't insert duplicates return } else if comp == 1 { inputlist.InsertBefore(item, e) return } } // if it wasn't already added, put in in the back inputlist.PushBack(item) }
func (s *Segment) mergeEnglishSpecialWord(orginalText []rune, wordInfoList *list.List, current *list.Element) (bool, *list.Element) { cur := current cur = cur.Next() last := -1 for cur != nil { if cur.Value.(*dict.WordInfo).WordType == dict.TSymbol || cur.Value.(*dict.WordInfo).WordType == dict.TEnglish { last = cur.Value.(*dict.WordInfo).Position + utils.RuneLen(cur.Value.(*dict.WordInfo).Word) cur = cur.Next() } else { break } } if last >= 0 { first := current.Value.(*dict.WordInfo).Position newWord := orginalText[first:last] wa := s.wordDictionary.GetWordAttr(newWord) if wa == nil { return false, current } for current != cur { removeItem := current current = current.Next() wordInfoList.Remove(removeItem) } wi := dict.NewWordInfoDefault() wi.Word = string(newWord) wi.Pos = wa.Pos wi.Frequency = wa.Frequency wi.WordType = dict.TEnglish wi.Position = first wi.Rank = s.params.EnglishRank if current == nil { wordInfoList.PushBack(wi) } else { wordInfoList.InsertBefore(wi, current) } return true, current } return false, current }
// Insert the given score into the given list func insertScore(scores *list.List, length int, s score) { // Loop through the scores for e := scores.Front(); e != nil; e = e.Next() { if e == scores.Back() { scores.InsertAfter(s, e) break } v, ok := e.Value.(score) if !ok { log.Fatal("Could not extract score from sorted list") } if s.score > v.score { scores.InsertBefore(s, e) break } } // Remove the last entry if the list is too long if scores.Len() > length { scores.Remove(scores.Back()) } }
//findType (1: findNode. 2: findValue) func IterativeFind(k *Kademlia, searchID ID, findType int) (bool, []FoundNode, []byte, error) { var value []byte var shortList *list.List //shortlist is the list we are going to return var closestNode ID var localContact *Contact = &(k.ContactInfo) var sentMap map[ID]bool //map of nodes we've sent rpcs to var liveMap map[ID]bool //map of nodes we've gotten responses from var kClosestArray []FoundNode var err error dbg.Printf("IterativeFind: searchID=%s findType:%d\n", Verbose, searchID.AsString(), findType) shortList = list.New() //list of kConst nodes we're considering sentMap = make(map[ID]bool) liveMap = make(map[ID]bool) kClosestArray, err = FindKClosest(k, searchID, localContact.NodeID) Assert(err == nil, "Kill yourself and fix me") Assert(len(kClosestArray) > 0, "I don't know anyone!") //adds len(KClosestArray) nodes to the shortList in order for i := 0; (i < KConst) && (i < len(kClosestArray)); i++ { var newNode *FoundNode var newNodeDist int newNode = &kClosestArray[i] newNodeDist = newNode.NodeID.Distance(searchID) var e *list.Element = shortList.Front() for ; e != nil; e = e.Next() { var dist int dist = e.Value.(*FoundNode).NodeID.Distance(searchID) //if responseNode is closer than node in ShortList, add it if newNodeDist < dist { shortList.InsertBefore(newNode, e) //node inserted! getout break } } if e == nil { //node is farthest yet shortList.PushBack(newNode) } } //set closestNode to first item from shortlist closestNode = shortList.Front().Value.(*FoundNode).NodeID var stillProgress bool = true NodeChan := make(chan *FindStarCallResponse, AConst) for stillProgress { var i int stillProgress = false //log.Printf("in main findNode iterative loop. shortList.Len()=%d len(liveMap)=%d\n", shortList.Len(),len(liveMap)) e := shortList.Front() for i = 0; i < AConst && e != nil; e = e.Next() { foundNodeTriplet := e.Value.(*FoundNode) _, inSentList := sentMap[foundNodeTriplet.NodeID] if inSentList { //don't do RPC on nodes in SentList //don't increment i (essentially the sentNodes counter) continue } //send rpc if findType == 1 { //FindNode //made MakeFindNodeCall take a channel, where it puts the result if RunningTests { Printf("makeFindNodeCall to ID=%s\n", k, Verbose, foundNodeTriplet.NodeID.AsString()) } go MakeFindNodeCall(k, foundNodeTriplet.FoundNodeToContact(), searchID, NodeChan) } else if findType == 2 { //FindValue if RunningTests { Printf("makeFindValueCall to ID=%s\n", k, Verbose, foundNodeTriplet.NodeID.AsString()) } go MakeFindValueCall(k, foundNodeTriplet.FoundNodeToContact(), searchID, NodeChan) } else { Assert(false, "Unknown case") } //put to sendList sentMap[foundNodeTriplet.NodeID] = true //e = e.Next() i++ //log.Printf("iterativeFindNode Find* rpc loop end\n") } //log.Printf("iterativeFind: Made FindNodeCall on %d hosts\n", i) var numProbs = i //wait for reply for i = 0; i < numProbs; i++ { //log.Printf("IterativeFind: α loop start\n") var foundStarResult *FindStarCallResponse foundStarResult = <-NodeChan if RunningTests { Printf("IterativeFind: Reading response from: %s\n", k, Verbose, foundStarResult.Responder.NodeID.AsString()) } //TODO: CRASHES IF ALL ALPHA RETURN EMPTY if foundStarResult.Responded { //Non data trash //Take its data liveMap[foundStarResult.Responder.NodeID] = true if findType == 1 { //FindNode Assert(foundStarResult.ReturnedFNRes != nil, "findStarResult Struct error in iterativeFindNode") addResponseNodesToSL(foundStarResult.ReturnedFNRes.Nodes, shortList, sentMap, searchID) } else { //FindValue Assert(foundStarResult.ReturnedFVRes != nil, "findStarResult Struct error in iterativeFindValue") //log.Printf("got response from %+v findvalue _%s_\n", foundStarResult.ReturnedFVRes, string(foundStarResult.ReturnedFVRes.Value)) if foundStarResult.ReturnedFVRes.Value != nil { var nArray []FoundNode = []FoundNode{*(foundStarResult.Responder)} //TODO //When an iterativeFindValue succeeds, the initiator must store the key/value pair at the closest node seen which did not return the value. return true, nArray, foundStarResult.ReturnedFVRes.Value, nil } else { if RunningTests { Printf("Could not found value in this node", k, Verbose) } } addResponseNodesToSL(foundStarResult.ReturnedFVRes.Nodes, shortList, sentMap, searchID) } distance := searchID.Distance(shortList.Front().Value.(*FoundNode).NodeID) if distance < searchID.Distance(closestNode) { //log.Printf("New closest! dist:%d\n", distance) closestNode = foundStarResult.Responder.NodeID stillProgress = true } else { //closestNode didn't change, flood RPCs and prep to return stillProgress = false } } else { dbg.Printf("iterativeFind: node:%+v failed to respond, removing from shortlist\n", Verbose, foundStarResult.Responder) //It failed, remove it from the shortlist for e := shortList.Front(); e != nil; e = e.Next() { if e.Value.(*FoundNode).NodeID.Equals(foundStarResult.Responder.NodeID) { shortList.Remove(e) break } } } //log.Printf("IterativeFind: α loop end\n") } } shortArray, value := sendRPCsToFoundNodes(k, findType, localContact, searchID, shortList, sentMap, liveMap) if findType == 1 { if Verbose { PrintArrayOfFoundNodes(&shortArray) } return true, shortArray, value, nil } else if findType == 2 && value != nil { return true, shortArray, value, nil } //if we're here and we were looking for a value, we failed. return false and foundnodes. return false, shortArray, value, nil }