Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swarm/pot: each() functions refactored #18452

Merged
merged 1 commit into from
Jan 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions swarm/network/kademlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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++
Expand All @@ -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
Expand All @@ -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++
Expand Down Expand Up @@ -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
})
Expand Down
74 changes: 32 additions & 42 deletions swarm/pot/pot.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
// 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
}
for _, n := range t.bins {
if n == nil {
return true
}
next = n.each(f)
if !next {
if !n.each(f) {
return false
}
}
if t.size == 0 {
return false
}
return f(t.pin, t.po)
return f(t.pin)
}

// 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 {
// 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, t.po)
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
}
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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()
}
Expand All @@ -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()
}
Expand Down
48 changes: 17 additions & 31 deletions swarm/pot/pot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gluk256 why is this test removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because i have removed the corresponding variable / return value

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal representation of PO does not have any meaning

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),
Expand All @@ -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)
}
}

Expand All @@ -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) {
Expand All @@ -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 {
Expand Down Expand Up @@ -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
}
Expand Down