swarm/pot: each() functions refactored (#18452)
This commit is contained in:
parent
1636d9574b
commit
4aeeecfded
@ -198,7 +198,7 @@ func (k *Kademlia) SuggestPeer() (a *BzzAddr, o int, want bool) {
|
||||
|
||||
var bpo []int
|
||||
prev := -1
|
||||
k.conns.EachBin(k.base, Pof, 0, func(po, size int, f func(func(val pot.Val, i int) bool) bool) bool {
|
||||
k.conns.EachBin(k.base, Pof, 0, func(po, size int, f func(func(val pot.Val) bool) bool) bool {
|
||||
prev++
|
||||
for ; prev < po; prev++ {
|
||||
bpo = append(bpo, prev)
|
||||
@ -219,12 +219,12 @@ func (k *Kademlia) SuggestPeer() (a *BzzAddr, o int, want bool) {
|
||||
// try to select a candidate peer
|
||||
// find the first callable peer
|
||||
nxt := bpo[0]
|
||||
k.addrs.EachBin(k.base, Pof, nxt, func(po, _ int, f func(func(pot.Val, int) bool) bool) bool {
|
||||
k.addrs.EachBin(k.base, Pof, nxt, func(po, _ int, f func(func(pot.Val) bool) bool) bool {
|
||||
// for each bin (up until depth) we find callable candidate peers
|
||||
if po >= depth {
|
||||
return false
|
||||
}
|
||||
return f(func(val pot.Val, _ int) bool {
|
||||
return f(func(val pot.Val) bool {
|
||||
e := val.(*entry)
|
||||
c := k.callable(e)
|
||||
if c {
|
||||
@ -442,7 +442,7 @@ func depthForPot(p *pot.Pot, neighbourhoodSize int, pivotAddr []byte) (depth int
|
||||
// the second step is to test for empty bins in order from shallowest to deepest
|
||||
// if an empty bin is found, this will be the actual depth
|
||||
// we stop iterating if we hit the maxDepth determined in the first step
|
||||
p.EachBin(pivotAddr, Pof, 0, func(po int, _ int, f func(func(pot.Val, int) bool) bool) bool {
|
||||
p.EachBin(pivotAddr, Pof, 0, func(po int, _ int, f func(func(pot.Val) bool) bool) bool {
|
||||
if po == depth {
|
||||
if maxDepth == depth {
|
||||
return false
|
||||
@ -514,14 +514,14 @@ func (k *Kademlia) string() string {
|
||||
|
||||
depth := depthForPot(k.conns, k.NeighbourhoodSize, k.base)
|
||||
rest := k.conns.Size()
|
||||
k.conns.EachBin(k.base, Pof, 0, func(po, size int, f func(func(val pot.Val, i int) bool) bool) bool {
|
||||
k.conns.EachBin(k.base, Pof, 0, func(po, size int, f func(func(val pot.Val) bool) bool) bool {
|
||||
var rowlen int
|
||||
if po >= k.MaxProxDisplay {
|
||||
po = k.MaxProxDisplay - 1
|
||||
}
|
||||
row := []string{fmt.Sprintf("%2d", size)}
|
||||
rest -= size
|
||||
f(func(val pot.Val, vpo int) bool {
|
||||
f(func(val pot.Val) bool {
|
||||
e := val.(*Peer)
|
||||
row = append(row, fmt.Sprintf("%x", e.Address()[:2]))
|
||||
rowlen++
|
||||
@ -533,7 +533,7 @@ func (k *Kademlia) string() string {
|
||||
return true
|
||||
})
|
||||
|
||||
k.addrs.EachBin(k.base, Pof, 0, func(po, size int, f func(func(val pot.Val, i int) bool) bool) bool {
|
||||
k.addrs.EachBin(k.base, Pof, 0, func(po, size int, f func(func(val pot.Val) bool) bool) bool {
|
||||
var rowlen int
|
||||
if po >= k.MaxProxDisplay {
|
||||
po = k.MaxProxDisplay - 1
|
||||
@ -543,7 +543,7 @@ func (k *Kademlia) string() string {
|
||||
}
|
||||
row := []string{fmt.Sprintf("%2d", size)}
|
||||
// we are displaying live peers too
|
||||
f(func(val pot.Val, vpo int) bool {
|
||||
f(func(val pot.Val) bool {
|
||||
e := val.(*entry)
|
||||
row = append(row, Label(e))
|
||||
rowlen++
|
||||
@ -634,7 +634,7 @@ func NewPeerPotMap(neighbourhoodSize int, addrs [][]byte) map[string]*PeerPot {
|
||||
// TODO this function will stop at the first bin with less than MinBinSize peers, even if there are empty bins between that bin and the depth. This may not be correct behavior
|
||||
func (k *Kademlia) saturation() int {
|
||||
prev := -1
|
||||
k.addrs.EachBin(k.base, Pof, 0, func(po, size int, f func(func(val pot.Val, i int) bool) bool) bool {
|
||||
k.addrs.EachBin(k.base, Pof, 0, func(po, size int, f func(func(val pot.Val) bool) bool) bool {
|
||||
prev++
|
||||
return prev == po && size >= k.MinBinSize
|
||||
})
|
||||
|
@ -447,60 +447,50 @@ func union(t0, t1 *Pot, pof Pof) (*Pot, int) {
|
||||
return n, common
|
||||
}
|
||||
|
||||
// Each called with (f) is a synchronous iterator over the bins of a node
|
||||
// respecting an ordering
|
||||
// proximity > pinnedness
|
||||
func (t *Pot) Each(f func(Val, int) bool) bool {
|
||||
// Each is a synchronous iterator over the elements of pot with function f.
|
||||
func (t *Pot) Each(f func(Val) bool) bool {
|
||||
return t.each(f)
|
||||
}
|
||||
|
||||
func (t *Pot) each(f func(Val, int) bool) bool {
|
||||
var next bool
|
||||
for _, n := range t.bins {
|
||||
if n == nil {
|
||||
return true
|
||||
}
|
||||
next = n.each(f)
|
||||
if !next {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if t.size == 0 {
|
||||
// each is a synchronous iterator over the elements of pot with function f.
|
||||
// the iteration ends if the function return false or there are no more elements.
|
||||
func (t *Pot) each(f func(Val) bool) bool {
|
||||
if t == nil || t.size == 0 {
|
||||
return false
|
||||
}
|
||||
return f(t.pin, t.po)
|
||||
}
|
||||
|
||||
// eachFrom called with (f, start) is a synchronous iterator over the elements of a Pot
|
||||
// within the inclusive range starting from proximity order start
|
||||
// the function argument is passed the value and the proximity order wrt the root pin
|
||||
// it does NOT include the pinned item of the root
|
||||
// respecting an ordering
|
||||
// proximity > pinnedness
|
||||
// the iteration ends if the function return false or there are no more elements
|
||||
// end of a po range can be implemented since po is passed to the function
|
||||
func (t *Pot) eachFrom(f func(Val, int) bool, po int) bool {
|
||||
var next bool
|
||||
_, lim := t.getPos(po)
|
||||
for i := lim; i < len(t.bins); i++ {
|
||||
n := t.bins[i]
|
||||
next = n.each(f)
|
||||
if !next {
|
||||
for _, n := range t.bins {
|
||||
if !n.each(f) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return f(t.pin, t.po)
|
||||
return f(t.pin)
|
||||
}
|
||||
|
||||
// eachFrom is a synchronous iterator over the elements of pot with function f,
|
||||
// starting from certain proximity order po, which is passed as a second parameter.
|
||||
// the iteration ends if the function return false or there are no more elements.
|
||||
func (t *Pot) eachFrom(f func(Val) bool, po int) bool {
|
||||
if t == nil || t.size == 0 {
|
||||
return false
|
||||
}
|
||||
_, beg := t.getPos(po)
|
||||
for i := beg; i < len(t.bins); i++ {
|
||||
if !t.bins[i].each(f) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return f(t.pin)
|
||||
}
|
||||
|
||||
// EachBin iterates over bins of the pivot node and offers iterators to the caller on each
|
||||
// subtree passing the proximity order and the size
|
||||
// the iteration continues until the function's return value is false
|
||||
// or there are no more subtries
|
||||
func (t *Pot) EachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val, i int) bool) bool) bool) {
|
||||
func (t *Pot) EachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val) bool) bool) bool) {
|
||||
t.eachBin(val, pof, po, f)
|
||||
}
|
||||
|
||||
func (t *Pot) eachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val, i int) bool) bool) bool) {
|
||||
func (t *Pot) eachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val) bool) bool) bool) {
|
||||
if t == nil || t.size == 0 {
|
||||
return
|
||||
}
|
||||
@ -520,8 +510,8 @@ func (t *Pot) eachBin(val Val, pof Pof, po int, f func(int, int, func(func(val V
|
||||
}
|
||||
if lim == len(t.bins) {
|
||||
if spr >= po {
|
||||
f(spr, 1, func(g func(Val, int) bool) bool {
|
||||
return g(t.pin, spr)
|
||||
f(spr, 1, func(g func(Val) bool) bool {
|
||||
return g(t.pin)
|
||||
})
|
||||
}
|
||||
return
|
||||
@ -535,9 +525,9 @@ func (t *Pot) eachBin(val Val, pof Pof, po int, f func(int, int, func(func(val V
|
||||
size += n.size
|
||||
}
|
||||
if spr >= po {
|
||||
if !f(spr, t.size-size, func(g func(Val, int) bool) bool {
|
||||
return t.eachFrom(func(v Val, j int) bool {
|
||||
return g(v, spr)
|
||||
if !f(spr, t.size-size, func(g func(Val) bool) bool {
|
||||
return t.eachFrom(func(v Val) bool {
|
||||
return g(v)
|
||||
}, spo)
|
||||
}) {
|
||||
return
|
||||
@ -585,7 +575,7 @@ func (t *Pot) eachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool {
|
||||
}
|
||||
|
||||
for i := l - 1; i > ir; i-- {
|
||||
next = t.bins[i].each(func(v Val, _ int) bool {
|
||||
next = t.bins[i].each(func(v Val) bool {
|
||||
return f(v, po)
|
||||
})
|
||||
if !next {
|
||||
@ -595,7 +585,7 @@ func (t *Pot) eachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool {
|
||||
|
||||
for i := il - 1; i >= 0; i-- {
|
||||
n := t.bins[i]
|
||||
next = n.each(func(v Val, _ int) bool {
|
||||
next = n.each(func(v Val) bool {
|
||||
return f(v, n.po)
|
||||
})
|
||||
if !next {
|
||||
@ -709,7 +699,7 @@ func (t *Pot) eachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(V
|
||||
wg.Add(m)
|
||||
}
|
||||
go func(pn *Pot, pm int) {
|
||||
pn.each(func(v Val, _ int) bool {
|
||||
pn.each(func(v Val) bool {
|
||||
if wg != nil {
|
||||
defer wg.Done()
|
||||
}
|
||||
@ -736,7 +726,7 @@ func (t *Pot) eachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(V
|
||||
wg.Add(m)
|
||||
}
|
||||
go func(pn *Pot, pm int) {
|
||||
pn.each(func(v Val, _ int) bool {
|
||||
pn.each(func(v Val) bool {
|
||||
if wg != nil {
|
||||
defer wg.Done()
|
||||
}
|
||||
|
@ -65,14 +65,13 @@ func randomtestAddr(n int, i int) *testAddr {
|
||||
return newTestAddr(v, i)
|
||||
}
|
||||
|
||||
func indexes(t *Pot) (i []int, po []int) {
|
||||
t.Each(func(v Val, p int) bool {
|
||||
func indexes(t *Pot) (i []int) {
|
||||
t.Each(func(v Val) bool {
|
||||
a := v.(*testAddr)
|
||||
i = append(i, a.i)
|
||||
po = append(po, p)
|
||||
return true
|
||||
})
|
||||
return i, po
|
||||
return i
|
||||
}
|
||||
|
||||
func testAdd(t *Pot, pof Pof, j int, values ...string) (_ *Pot, n int, f bool) {
|
||||
@ -102,23 +101,18 @@ func TestPotRemoveSameBin(t *testing.T) {
|
||||
n := NewPot(newTestAddr("11111111", 0), 0)
|
||||
n, _, _ = testAdd(n, pof, 1, "00000000", "01000000", "01100000", "01110000", "01111000")
|
||||
n, _, _ = Remove(n, newTestAddr("01110000", 0), pof)
|
||||
inds, po := indexes(n)
|
||||
inds := indexes(n)
|
||||
goti := n.Size()
|
||||
expi := 5
|
||||
if goti != expi {
|
||||
t.Fatalf("incorrect number of elements in Pot. Expected %v, got %v", expi, goti)
|
||||
}
|
||||
inds, po = indexes(n)
|
||||
inds = indexes(n)
|
||||
got := fmt.Sprintf("%v", inds)
|
||||
exp := "[5 3 2 1 0]"
|
||||
if got != exp {
|
||||
t.Fatalf("incorrect indexes in iteration over Pot. Expected %v, got %v", exp, got)
|
||||
}
|
||||
got = fmt.Sprintf("%v", po)
|
||||
exp = "[3 2 1 0 0]"
|
||||
if got != exp {
|
||||
t.Fatalf("incorrect po-s in iteration over Pot. Expected %v, got %v", exp, got)
|
||||
}
|
||||
}
|
||||
|
||||
// this test creates a flat pot tree (all the elements are leafs of one root),
|
||||
@ -129,22 +123,24 @@ func TestPotRemoveDifferentBins(t *testing.T) {
|
||||
n := NewPot(newTestAddr("11111111", 0), 0)
|
||||
n, _, _ = testAdd(n, pof, 1, "00000000", "10000000", "11000000", "11100000", "11110000")
|
||||
n, _, _ = Remove(n, newTestAddr("11100000", 0), pof)
|
||||
inds, po := indexes(n)
|
||||
inds := indexes(n)
|
||||
goti := n.Size()
|
||||
expi := 5
|
||||
if goti != expi {
|
||||
t.Fatalf("incorrect number of elements in Pot. Expected %v, got %v", expi, goti)
|
||||
}
|
||||
inds, po = indexes(n)
|
||||
inds = indexes(n)
|
||||
got := fmt.Sprintf("%v", inds)
|
||||
exp := "[1 2 3 5 0]"
|
||||
if got != exp {
|
||||
t.Fatalf("incorrect indexes in iteration over Pot. Expected %v, got %v", exp, got)
|
||||
}
|
||||
got = fmt.Sprintf("%v", po)
|
||||
exp = "[0 1 2 4 0]"
|
||||
n, _, _ = testAdd(n, pof, 4, "11100000")
|
||||
inds = indexes(n)
|
||||
got = fmt.Sprintf("%v", inds)
|
||||
exp = "[1 2 3 4 5 0]"
|
||||
if got != exp {
|
||||
t.Fatalf("incorrect po-s in iteration over Pot. Expected %v, got %v", exp, got)
|
||||
t.Fatalf("incorrect indexes in iteration over Pot. Expected %v, got %v", exp, got)
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,17 +167,12 @@ func TestPotAdd(t *testing.T) {
|
||||
if goti != expi {
|
||||
t.Fatalf("incorrect number of elements in Pot. Expected %v, got %v", expi, goti)
|
||||
}
|
||||
inds, po := indexes(n)
|
||||
inds := indexes(n)
|
||||
got = fmt.Sprintf("%v", inds)
|
||||
exp = "[3 4 2]"
|
||||
if got != exp {
|
||||
t.Fatalf("incorrect indexes in iteration over Pot. Expected %v, got %v", exp, got)
|
||||
}
|
||||
got = fmt.Sprintf("%v", po)
|
||||
exp = "[1 2 0]"
|
||||
if got != exp {
|
||||
t.Fatalf("incorrect po-s in iteration over Pot. Expected %v, got %v", exp, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPotRemove(t *testing.T) {
|
||||
@ -200,25 +191,20 @@ func TestPotRemove(t *testing.T) {
|
||||
if goti != expi {
|
||||
t.Fatalf("incorrect number of elements in Pot. Expected %v, got %v", expi, goti)
|
||||
}
|
||||
inds, po := indexes(n)
|
||||
got = fmt.Sprintf("%v", po)
|
||||
exp = "[1 3 0]"
|
||||
if got != exp {
|
||||
t.Fatalf("incorrect po-s in iteration over Pot. Expected %v, got %v", exp, got)
|
||||
}
|
||||
inds := indexes(n)
|
||||
got = fmt.Sprintf("%v", inds)
|
||||
exp = "[2 4 1]"
|
||||
if got != exp {
|
||||
t.Fatalf("incorrect indexes in iteration over Pot. Expected %v, got %v", exp, got)
|
||||
}
|
||||
n, _, _ = Remove(n, newTestAddr("00111100", 0), pof) // remove again same element
|
||||
inds, _ = indexes(n)
|
||||
inds = indexes(n)
|
||||
got = fmt.Sprintf("%v", inds)
|
||||
if got != exp {
|
||||
t.Fatalf("incorrect indexes in iteration over Pot. Expected %v, got %v", exp, got)
|
||||
}
|
||||
n, _, _ = Remove(n, newTestAddr("00000000", 0), pof) // remove the first element
|
||||
inds, _ = indexes(n)
|
||||
inds = indexes(n)
|
||||
got = fmt.Sprintf("%v", inds)
|
||||
exp = "[2 4]"
|
||||
if got != exp {
|
||||
@ -272,7 +258,7 @@ func TestPotSwap(t *testing.T) {
|
||||
})
|
||||
}
|
||||
sum := 0
|
||||
n.Each(func(v Val, i int) bool {
|
||||
n.Each(func(v Val) bool {
|
||||
if v == nil {
|
||||
return true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user