ipld-eth-server/vendor/github.com/libp2p/go-libp2p-kbucket/bucket.go
Elizabeth Engelman 36533f7c3f Update vendor directory and make necessary code changes
Fixes for new geth version
2019-09-25 16:32:27 -05:00

111 lines
2.0 KiB
Go

package kbucket
import (
"container/list"
"sync"
"github.com/libp2p/go-libp2p-core/peer"
)
// Bucket holds a list of peers.
type Bucket struct {
lk sync.RWMutex
list *list.List
}
func newBucket() *Bucket {
b := new(Bucket)
b.list = list.New()
return b
}
func (b *Bucket) Peers() []peer.ID {
b.lk.RLock()
defer b.lk.RUnlock()
ps := make([]peer.ID, 0, b.list.Len())
for e := b.list.Front(); e != nil; e = e.Next() {
id := e.Value.(peer.ID)
ps = append(ps, id)
}
return ps
}
func (b *Bucket) Has(id peer.ID) bool {
b.lk.RLock()
defer b.lk.RUnlock()
for e := b.list.Front(); e != nil; e = e.Next() {
if e.Value.(peer.ID) == id {
return true
}
}
return false
}
func (b *Bucket) Remove(id peer.ID) bool {
b.lk.Lock()
defer b.lk.Unlock()
for e := b.list.Front(); e != nil; e = e.Next() {
if e.Value.(peer.ID) == id {
b.list.Remove(e)
return true
}
}
return false
}
func (b *Bucket) MoveToFront(id peer.ID) {
b.lk.Lock()
defer b.lk.Unlock()
for e := b.list.Front(); e != nil; e = e.Next() {
if e.Value.(peer.ID) == id {
b.list.MoveToFront(e)
}
}
}
func (b *Bucket) PushFront(p peer.ID) {
b.lk.Lock()
b.list.PushFront(p)
b.lk.Unlock()
}
func (b *Bucket) PopBack() peer.ID {
b.lk.Lock()
defer b.lk.Unlock()
last := b.list.Back()
b.list.Remove(last)
return last.Value.(peer.ID)
}
func (b *Bucket) Len() int {
b.lk.RLock()
defer b.lk.RUnlock()
return b.list.Len()
}
// Split splits a buckets peers into two buckets, the methods receiver will have
// peers with CPL equal to cpl, the returned bucket will have peers with CPL
// greater than cpl (returned bucket has closer peers)
func (b *Bucket) Split(cpl int, target ID) *Bucket {
b.lk.Lock()
defer b.lk.Unlock()
out := list.New()
newbuck := newBucket()
newbuck.list = out
e := b.list.Front()
for e != nil {
peerID := ConvertPeerID(e.Value.(peer.ID))
peerCPL := CommonPrefixLen(peerID, target)
if peerCPL > cpl {
cur := e
out.PushBack(e.Value)
e = e.Next()
b.list.Remove(cur)
continue
}
e = e.Next()
}
return newbuck
}