Commit e29c4cd4 authored by Janoš Guljaš's avatar Janoš Guljaš Committed by GitHub

proximity function adjustments (#286)

parent c8e5969d
...@@ -169,7 +169,7 @@ func (k *Kad) manage() { ...@@ -169,7 +169,7 @@ func (k *Kad) manage() {
if err != nil { if err != nil {
if errors.Is(err, errMissingAddressBookEntry) { if errors.Is(err, errMissingAddressBookEntry) {
po := uint8(swarm.Proximity(k.base.Bytes(), peerToRemove.Bytes())) po := swarm.Proximity(k.base.Bytes(), peerToRemove.Bytes())
k.knownPeers.Remove(peerToRemove, po) k.knownPeers.Remove(peerToRemove, po)
} else { } else {
k.logger.Errorf("kademlia manage loop iterator: %v", err) k.logger.Errorf("kademlia manage loop iterator: %v", err)
...@@ -292,7 +292,7 @@ func (k *Kad) AddPeer(ctx context.Context, addr swarm.Address) error { ...@@ -292,7 +292,7 @@ func (k *Kad) AddPeer(ctx context.Context, addr swarm.Address) error {
} }
po := swarm.Proximity(k.base.Bytes(), addr.Bytes()) po := swarm.Proximity(k.base.Bytes(), addr.Bytes())
k.knownPeers.Add(addr, uint8(po)) k.knownPeers.Add(addr, po)
select { select {
case k.manageC <- struct{}{}: case k.manageC <- struct{}{}:
...@@ -304,7 +304,7 @@ func (k *Kad) AddPeer(ctx context.Context, addr swarm.Address) error { ...@@ -304,7 +304,7 @@ func (k *Kad) AddPeer(ctx context.Context, addr swarm.Address) error {
// Connected is called when a peer has dialed in. // Connected is called when a peer has dialed in.
func (k *Kad) Connected(ctx context.Context, addr swarm.Address) error { func (k *Kad) Connected(ctx context.Context, addr swarm.Address) error {
po := uint8(swarm.Proximity(k.base.Bytes(), addr.Bytes())) po := swarm.Proximity(k.base.Bytes(), addr.Bytes())
k.knownPeers.Add(addr, po) k.knownPeers.Add(addr, po)
k.connectedPeers.Add(addr, po) k.connectedPeers.Add(addr, po)
...@@ -325,7 +325,7 @@ func (k *Kad) Connected(ctx context.Context, addr swarm.Address) error { ...@@ -325,7 +325,7 @@ func (k *Kad) Connected(ctx context.Context, addr swarm.Address) error {
// Disconnected is called when peer disconnects. // Disconnected is called when peer disconnects.
func (k *Kad) Disconnected(addr swarm.Address) { func (k *Kad) Disconnected(addr swarm.Address) {
po := uint8(swarm.Proximity(k.base.Bytes(), addr.Bytes())) po := swarm.Proximity(k.base.Bytes(), addr.Bytes())
k.connectedPeers.Remove(addr, po) k.connectedPeers.Remove(addr, po)
k.waitNextMu.Lock() k.waitNextMu.Lock()
......
...@@ -74,7 +74,7 @@ func TestShallowestEmpty(t *testing.T) { ...@@ -74,7 +74,7 @@ func TestShallowestEmpty(t *testing.T) {
}, },
} { } {
for _, v := range peers[tc.removePo] { for _, v := range peers[tc.removePo] {
po := uint8(swarm.Proximity(base.Bytes(), v.Bytes())) po := swarm.Proximity(base.Bytes(), v.Bytes())
ps.Remove(v, po) ps.Remove(v, po)
} }
sd, none := ps.ShallowestEmpty() sd, none := ps.ShallowestEmpty()
......
...@@ -441,7 +441,7 @@ func (db *DB) Close() (err error) { ...@@ -441,7 +441,7 @@ func (db *DB) Close() (err error) {
// po computes the proximity order between the address // po computes the proximity order between the address
// and database base key. // and database base key.
func (db *DB) po(addr swarm.Address) (bin uint8) { func (db *DB) po(addr swarm.Address) (bin uint8) {
return uint8(swarm.Proximity(db.baseKey, addr.Bytes())) return swarm.Proximity(db.baseKey, addr.Bytes())
} }
// DebugIndices returns the index sizes for all indexes in localstore // DebugIndices returns the index sizes for all indexes in localstore
......
...@@ -99,7 +99,7 @@ func TestDB_SubscribePull(t *testing.T) { ...@@ -99,7 +99,7 @@ func TestDB_SubscribePull(t *testing.T) {
// to validate the number of addresses received by the subscription // to validate the number of addresses received by the subscription
errChan := make(chan error) errChan := make(chan error)
for bin := uint8(0); bin <= uint8(swarm.MaxPO); bin++ { for bin := uint8(0); bin <= swarm.MaxPO; bin++ {
ch, stop := db.SubscribePull(ctx, bin, 0, 0) ch, stop := db.SubscribePull(ctx, bin, 0, 0)
defer stop() defer stop()
...@@ -148,7 +148,7 @@ func TestDB_SubscribePull_multiple(t *testing.T) { ...@@ -148,7 +148,7 @@ func TestDB_SubscribePull_multiple(t *testing.T) {
// start a number of subscriptions // start a number of subscriptions
// that all of them will write every address error to errChan // that all of them will write every address error to errChan
for j := 0; j < subsCount; j++ { for j := 0; j < subsCount; j++ {
for bin := uint8(0); bin <= uint8(swarm.MaxPO); bin++ { for bin := uint8(0); bin <= swarm.MaxPO; bin++ {
ch, stop := db.SubscribePull(ctx, bin, 0, 0) ch, stop := db.SubscribePull(ctx, bin, 0, 0)
defer stop() defer stop()
...@@ -232,7 +232,7 @@ func TestDB_SubscribePull_since(t *testing.T) { ...@@ -232,7 +232,7 @@ func TestDB_SubscribePull_since(t *testing.T) {
// to validate the number of addresses received by the subscription // to validate the number of addresses received by the subscription
errChan := make(chan error) errChan := make(chan error)
for bin := uint8(0); bin <= uint8(swarm.MaxPO); bin++ { for bin := uint8(0); bin <= swarm.MaxPO; bin++ {
since, ok := first[bin] since, ok := first[bin]
if !ok { if !ok {
continue continue
...@@ -308,7 +308,7 @@ func TestDB_SubscribePull_until(t *testing.T) { ...@@ -308,7 +308,7 @@ func TestDB_SubscribePull_until(t *testing.T) {
// to validate the number of addresses received by the subscription // to validate the number of addresses received by the subscription
errChan := make(chan error) errChan := make(chan error)
for bin := uint8(0); bin <= uint8(swarm.MaxPO); bin++ { for bin := uint8(0); bin <= swarm.MaxPO; bin++ {
until, ok := last[bin] until, ok := last[bin]
if !ok { if !ok {
continue continue
...@@ -392,7 +392,7 @@ func TestDB_SubscribePull_sinceAndUntil(t *testing.T) { ...@@ -392,7 +392,7 @@ func TestDB_SubscribePull_sinceAndUntil(t *testing.T) {
// to validate the number of addresses received by the subscription // to validate the number of addresses received by the subscription
errChan := make(chan error) errChan := make(chan error)
for bin := uint8(0); bin <= uint8(swarm.MaxPO); bin++ { for bin := uint8(0); bin <= swarm.MaxPO; bin++ {
since, ok := upload1[bin] since, ok := upload1[bin]
if ok { if ok {
// start from the next uploaded chunk // start from the next uploaded chunk
...@@ -477,7 +477,7 @@ func TestDB_SubscribePull_rangeOnRemovedChunks(t *testing.T) { ...@@ -477,7 +477,7 @@ func TestDB_SubscribePull_rangeOnRemovedChunks(t *testing.T) {
// signals that there were valid bins for this check to ensure test validity // signals that there were valid bins for this check to ensure test validity
var checkedBins int var checkedBins int
// subscribe to every bin and validate returned values // subscribe to every bin and validate returned values
for bin := uint8(0); bin <= uint8(swarm.MaxPO); bin++ { for bin := uint8(0); bin <= swarm.MaxPO; bin++ {
// do not subscribe to bins that do not have chunks // do not subscribe to bins that do not have chunks
if len(chunks[bin]) == 0 { if len(chunks[bin]) == 0 {
continue continue
...@@ -645,7 +645,7 @@ func TestDB_LastPullSubscriptionBinID(t *testing.T) { ...@@ -645,7 +645,7 @@ func TestDB_LastPullSubscriptionBinID(t *testing.T) {
} }
// check // check
for bin := uint8(0); bin <= uint8(swarm.MaxPO); bin++ { for bin := uint8(0); bin <= swarm.MaxPO; bin++ {
want, ok := last[bin] want, ok := last[bin]
got, err := db.LastPullSubscriptionBinID(bin) got, err := db.LastPullSubscriptionBinID(bin)
if ok { if ok {
......
...@@ -17,16 +17,17 @@ package swarm ...@@ -17,16 +17,17 @@ package swarm
// binary representation of the x^y. // binary representation of the x^y.
// //
// (0 farthest, 255 closest, 256 self) // (0 farthest, 255 closest, 256 self)
func Proximity(one, other []byte) (ret int) { func Proximity(one, other []byte) (ret uint8) {
b := (MaxPO-1)/8 + 1 b := MaxPO/8 + 1
if b > len(one) { l := uint8(len(one))
b = len(one) if b > l {
b = l
} }
m := 8 var m uint8 = 8
for i := 0; i < b; i++ { for i := uint8(0); i < b; i++ {
oxo := one[i] ^ other[i] oxo := one[i] ^ other[i]
for j := 0; j < m; j++ { for j := uint8(0); j < m; j++ {
if (oxo>>uint8(7-j))&0x01 != 0 { if (oxo>>(7-j))&0x01 != 0 {
return i*8 + j return i*8 + j
} }
} }
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
package swarm package swarm
import ( import (
"strconv"
"testing" "testing"
) )
...@@ -25,14 +24,6 @@ import ( ...@@ -25,14 +24,6 @@ import (
// values in a table-driven test. It is highly dependant on // values in a table-driven test. It is highly dependant on
// MaxPO constant and it validates cases up to MaxPO=32. // MaxPO constant and it validates cases up to MaxPO=32.
func TestProximity(t *testing.T) { func TestProximity(t *testing.T) {
// integer from base2 encoded string
bx := func(s string) uint8 {
i, err := strconv.ParseUint(s, 2, 8)
if err != nil {
t.Fatal(err)
}
return uint8(i)
}
// adjust expected bins in respect to MaxPO // adjust expected bins in respect to MaxPO
limitPO := func(po uint8) uint8 { limitPO := func(po uint8) uint8 {
if po > MaxPO { if po > MaxPO {
...@@ -40,7 +31,7 @@ func TestProximity(t *testing.T) { ...@@ -40,7 +31,7 @@ func TestProximity(t *testing.T) {
} }
return po return po
} }
base := []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00000000")} base := []byte{0b00000000, 0b00000000, 0b00000000, 0b00000000}
for _, tc := range []struct { for _, tc := range []struct {
addr []byte addr []byte
po uint8 po uint8
...@@ -50,135 +41,135 @@ func TestProximity(t *testing.T) { ...@@ -50,135 +41,135 @@ func TestProximity(t *testing.T) {
po: MaxPO, po: MaxPO,
}, },
{ {
addr: []byte{bx("10000000"), bx("00000000"), bx("00000000"), bx("00000000")}, addr: []byte{0b10000000, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(0), po: limitPO(0),
}, },
{ {
addr: []byte{bx("01000000"), bx("00000000"), bx("00000000"), bx("00000000")}, addr: []byte{0b01000000, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(1), po: limitPO(1),
}, },
{ {
addr: []byte{bx("00100000"), bx("00000000"), bx("00000000"), bx("00000000")}, addr: []byte{0b00100000, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(2), po: limitPO(2),
}, },
{ {
addr: []byte{bx("00010000"), bx("00000000"), bx("00000000"), bx("00000000")}, addr: []byte{0b00010000, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(3), po: limitPO(3),
}, },
{ {
addr: []byte{bx("00001000"), bx("00000000"), bx("00000000"), bx("00000000")}, addr: []byte{0b00001000, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(4), po: limitPO(4),
}, },
{ {
addr: []byte{bx("00000100"), bx("00000000"), bx("00000000"), bx("00000000")}, addr: []byte{0b00000100, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(5), po: limitPO(5),
}, },
{ {
addr: []byte{bx("00000010"), bx("00000000"), bx("00000000"), bx("00000000")}, addr: []byte{0b00000010, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(6), po: limitPO(6),
}, },
{ {
addr: []byte{bx("00000001"), bx("00000000"), bx("00000000"), bx("00000000")}, addr: []byte{0b00000001, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(7), po: limitPO(7),
}, },
{ {
addr: []byte{bx("00000000"), bx("10000000"), bx("00000000"), bx("00000000")}, addr: []byte{0b00000000, 0b10000000, 0b00000000, 0b00000000},
po: limitPO(8), po: limitPO(8),
}, },
{ {
addr: []byte{bx("00000000"), bx("01000000"), bx("00000000"), bx("00000000")}, addr: []byte{0b00000000, 0b01000000, 0b00000000, 0b00000000},
po: limitPO(9), po: limitPO(9),
}, },
{ {
addr: []byte{bx("00000000"), bx("00100000"), bx("00000000"), bx("00000000")}, addr: []byte{0b00000000, 0b00100000, 0b00000000, 0b00000000},
po: limitPO(10), po: limitPO(10),
}, },
{ {
addr: []byte{bx("00000000"), bx("00010000"), bx("00000000"), bx("00000000")}, addr: []byte{0b00000000, 0b00010000, 0b00000000, 0b00000000},
po: limitPO(11), po: limitPO(11),
}, },
{ {
addr: []byte{bx("00000000"), bx("00001000"), bx("00000000"), bx("00000000")}, addr: []byte{0b00000000, 0b00001000, 0b00000000, 0b00000000},
po: limitPO(12), po: limitPO(12),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000100"), bx("00000000"), bx("00000000")}, addr: []byte{0b00000000, 0b00000100, 0b00000000, 0b00000000},
po: limitPO(13), po: limitPO(13),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000010"), bx("00000000"), bx("00000000")}, addr: []byte{0b00000000, 0b00000010, 0b00000000, 0b00000000},
po: limitPO(14), po: limitPO(14),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000001"), bx("00000000"), bx("00000000")}, addr: []byte{0b00000000, 0b00000001, 0b00000000, 0b00000000},
po: limitPO(15), po: limitPO(15),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("10000000"), bx("00000000")}, addr: []byte{0b00000000, 0b00000000, 0b10000000, 0b00000000},
po: limitPO(16), po: limitPO(16),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("01000000"), bx("00000000")}, addr: []byte{0b00000000, 0b00000000, 0b01000000, 0b00000000},
po: limitPO(17), po: limitPO(17),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00100000"), bx("00000000")}, addr: []byte{0b00000000, 0b00000000, 0b00100000, 0b00000000},
po: limitPO(18), po: limitPO(18),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00010000"), bx("00000000")}, addr: []byte{0b00000000, 0b00000000, 0b00010000, 0b00000000},
po: limitPO(19), po: limitPO(19),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00001000"), bx("00000000")}, addr: []byte{0b00000000, 0b00000000, 0b00001000, 0b00000000},
po: limitPO(20), po: limitPO(20),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00000100"), bx("00000000")}, addr: []byte{0b00000000, 0b00000000, 0b00000100, 0b00000000},
po: limitPO(21), po: limitPO(21),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00000010"), bx("00000000")}, addr: []byte{0b00000000, 0b00000000, 0b00000010, 0b00000000},
po: limitPO(22), po: limitPO(22),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00000001"), bx("00000000")}, addr: []byte{0b00000000, 0b00000000, 0b00000001, 0b00000000},
po: limitPO(23), po: limitPO(23),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("10000000")}, addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b10000000},
po: limitPO(24), po: limitPO(24),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("01000000")}, addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b01000000},
po: limitPO(25), po: limitPO(25),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00100000")}, addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b00100000},
po: limitPO(26), po: limitPO(26),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00010000")}, addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b00010000},
po: limitPO(27), po: limitPO(27),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00001000")}, addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b00001000},
po: limitPO(28), po: limitPO(28),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00000100")}, addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b00000100},
po: limitPO(29), po: limitPO(29),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00000010")}, addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b00000010},
po: limitPO(30), po: limitPO(30),
}, },
{ {
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00000001")}, addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b00000001},
po: limitPO(31), po: limitPO(31),
}, },
} { } {
got := uint8(Proximity(base, tc.addr)) got := Proximity(base, tc.addr)
if got != tc.po { if got != tc.po {
t.Errorf("got %v bin, want %v", got, tc.po) t.Errorf("got %v bin, want %v", got, tc.po)
} }
......
...@@ -13,11 +13,11 @@ import ( ...@@ -13,11 +13,11 @@ import (
) )
const ( const (
SectionSize = 32 SectionSize = 32
Branches = 128 Branches = 128
ChunkSize = SectionSize * Branches ChunkSize = SectionSize * Branches
HashSize = 32 HashSize = 32
MaxPO = 16 MaxPO uint8 = 15
) )
// Address represents an address in Swarm metric space of // Address represents an address in Swarm metric space of
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment