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() {
if err != nil {
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)
} else {
k.logger.Errorf("kademlia manage loop iterator: %v", err)
......@@ -292,7 +292,7 @@ func (k *Kad) AddPeer(ctx context.Context, addr swarm.Address) error {
}
po := swarm.Proximity(k.base.Bytes(), addr.Bytes())
k.knownPeers.Add(addr, uint8(po))
k.knownPeers.Add(addr, po)
select {
case k.manageC <- struct{}{}:
......@@ -304,7 +304,7 @@ func (k *Kad) AddPeer(ctx context.Context, addr swarm.Address) error {
// Connected is called when a peer has dialed in.
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.connectedPeers.Add(addr, po)
......@@ -325,7 +325,7 @@ func (k *Kad) Connected(ctx context.Context, addr swarm.Address) error {
// Disconnected is called when peer disconnects.
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.waitNextMu.Lock()
......
......@@ -74,7 +74,7 @@ func TestShallowestEmpty(t *testing.T) {
},
} {
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)
}
sd, none := ps.ShallowestEmpty()
......
......@@ -441,7 +441,7 @@ func (db *DB) Close() (err error) {
// po computes the proximity order between the address
// and database base key.
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
......
......@@ -99,7 +99,7 @@ func TestDB_SubscribePull(t *testing.T) {
// to validate the number of addresses received by the subscription
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)
defer stop()
......@@ -148,7 +148,7 @@ func TestDB_SubscribePull_multiple(t *testing.T) {
// start a number of subscriptions
// that all of them will write every address error to errChan
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)
defer stop()
......@@ -232,7 +232,7 @@ func TestDB_SubscribePull_since(t *testing.T) {
// to validate the number of addresses received by the subscription
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]
if !ok {
continue
......@@ -308,7 +308,7 @@ func TestDB_SubscribePull_until(t *testing.T) {
// to validate the number of addresses received by the subscription
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]
if !ok {
continue
......@@ -392,7 +392,7 @@ func TestDB_SubscribePull_sinceAndUntil(t *testing.T) {
// to validate the number of addresses received by the subscription
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]
if ok {
// start from the next uploaded chunk
......@@ -477,7 +477,7 @@ func TestDB_SubscribePull_rangeOnRemovedChunks(t *testing.T) {
// signals that there were valid bins for this check to ensure test validity
var checkedBins int
// 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
if len(chunks[bin]) == 0 {
continue
......@@ -645,7 +645,7 @@ func TestDB_LastPullSubscriptionBinID(t *testing.T) {
}
// check
for bin := uint8(0); bin <= uint8(swarm.MaxPO); bin++ {
for bin := uint8(0); bin <= swarm.MaxPO; bin++ {
want, ok := last[bin]
got, err := db.LastPullSubscriptionBinID(bin)
if ok {
......
......@@ -17,16 +17,17 @@ package swarm
// binary representation of the x^y.
//
// (0 farthest, 255 closest, 256 self)
func Proximity(one, other []byte) (ret int) {
b := (MaxPO-1)/8 + 1
if b > len(one) {
b = len(one)
func Proximity(one, other []byte) (ret uint8) {
b := MaxPO/8 + 1
l := uint8(len(one))
if b > l {
b = l
}
m := 8
for i := 0; i < b; i++ {
var m uint8 = 8
for i := uint8(0); i < b; i++ {
oxo := one[i] ^ other[i]
for j := 0; j < m; j++ {
if (oxo>>uint8(7-j))&0x01 != 0 {
for j := uint8(0); j < m; j++ {
if (oxo>>(7-j))&0x01 != 0 {
return i*8 + j
}
}
......
......@@ -17,7 +17,6 @@
package swarm
import (
"strconv"
"testing"
)
......@@ -25,14 +24,6 @@ import (
// values in a table-driven test. It is highly dependant on
// MaxPO constant and it validates cases up to MaxPO=32.
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
limitPO := func(po uint8) uint8 {
if po > MaxPO {
......@@ -40,7 +31,7 @@ func TestProximity(t *testing.T) {
}
return po
}
base := []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00000000")}
base := []byte{0b00000000, 0b00000000, 0b00000000, 0b00000000}
for _, tc := range []struct {
addr []byte
po uint8
......@@ -50,135 +41,135 @@ func TestProximity(t *testing.T) {
po: MaxPO,
},
{
addr: []byte{bx("10000000"), bx("00000000"), bx("00000000"), bx("00000000")},
addr: []byte{0b10000000, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(0),
},
{
addr: []byte{bx("01000000"), bx("00000000"), bx("00000000"), bx("00000000")},
addr: []byte{0b01000000, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(1),
},
{
addr: []byte{bx("00100000"), bx("00000000"), bx("00000000"), bx("00000000")},
addr: []byte{0b00100000, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(2),
},
{
addr: []byte{bx("00010000"), bx("00000000"), bx("00000000"), bx("00000000")},
addr: []byte{0b00010000, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(3),
},
{
addr: []byte{bx("00001000"), bx("00000000"), bx("00000000"), bx("00000000")},
addr: []byte{0b00001000, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(4),
},
{
addr: []byte{bx("00000100"), bx("00000000"), bx("00000000"), bx("00000000")},
addr: []byte{0b00000100, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(5),
},
{
addr: []byte{bx("00000010"), bx("00000000"), bx("00000000"), bx("00000000")},
addr: []byte{0b00000010, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(6),
},
{
addr: []byte{bx("00000001"), bx("00000000"), bx("00000000"), bx("00000000")},
addr: []byte{0b00000001, 0b00000000, 0b00000000, 0b00000000},
po: limitPO(7),
},
{
addr: []byte{bx("00000000"), bx("10000000"), bx("00000000"), bx("00000000")},
addr: []byte{0b00000000, 0b10000000, 0b00000000, 0b00000000},
po: limitPO(8),
},
{
addr: []byte{bx("00000000"), bx("01000000"), bx("00000000"), bx("00000000")},
addr: []byte{0b00000000, 0b01000000, 0b00000000, 0b00000000},
po: limitPO(9),
},
{
addr: []byte{bx("00000000"), bx("00100000"), bx("00000000"), bx("00000000")},
addr: []byte{0b00000000, 0b00100000, 0b00000000, 0b00000000},
po: limitPO(10),
},
{
addr: []byte{bx("00000000"), bx("00010000"), bx("00000000"), bx("00000000")},
addr: []byte{0b00000000, 0b00010000, 0b00000000, 0b00000000},
po: limitPO(11),
},
{
addr: []byte{bx("00000000"), bx("00001000"), bx("00000000"), bx("00000000")},
addr: []byte{0b00000000, 0b00001000, 0b00000000, 0b00000000},
po: limitPO(12),
},
{
addr: []byte{bx("00000000"), bx("00000100"), bx("00000000"), bx("00000000")},
addr: []byte{0b00000000, 0b00000100, 0b00000000, 0b00000000},
po: limitPO(13),
},
{
addr: []byte{bx("00000000"), bx("00000010"), bx("00000000"), bx("00000000")},
addr: []byte{0b00000000, 0b00000010, 0b00000000, 0b00000000},
po: limitPO(14),
},
{
addr: []byte{bx("00000000"), bx("00000001"), bx("00000000"), bx("00000000")},
addr: []byte{0b00000000, 0b00000001, 0b00000000, 0b00000000},
po: limitPO(15),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("10000000"), bx("00000000")},
addr: []byte{0b00000000, 0b00000000, 0b10000000, 0b00000000},
po: limitPO(16),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("01000000"), bx("00000000")},
addr: []byte{0b00000000, 0b00000000, 0b01000000, 0b00000000},
po: limitPO(17),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00100000"), bx("00000000")},
addr: []byte{0b00000000, 0b00000000, 0b00100000, 0b00000000},
po: limitPO(18),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00010000"), bx("00000000")},
addr: []byte{0b00000000, 0b00000000, 0b00010000, 0b00000000},
po: limitPO(19),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00001000"), bx("00000000")},
addr: []byte{0b00000000, 0b00000000, 0b00001000, 0b00000000},
po: limitPO(20),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00000100"), bx("00000000")},
addr: []byte{0b00000000, 0b00000000, 0b00000100, 0b00000000},
po: limitPO(21),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00000010"), bx("00000000")},
addr: []byte{0b00000000, 0b00000000, 0b00000010, 0b00000000},
po: limitPO(22),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00000001"), bx("00000000")},
addr: []byte{0b00000000, 0b00000000, 0b00000001, 0b00000000},
po: limitPO(23),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("10000000")},
addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b10000000},
po: limitPO(24),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("01000000")},
addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b01000000},
po: limitPO(25),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00100000")},
addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b00100000},
po: limitPO(26),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00010000")},
addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b00010000},
po: limitPO(27),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00001000")},
addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b00001000},
po: limitPO(28),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00000100")},
addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b00000100},
po: limitPO(29),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00000010")},
addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b00000010},
po: limitPO(30),
},
{
addr: []byte{bx("00000000"), bx("00000000"), bx("00000000"), bx("00000001")},
addr: []byte{0b00000000, 0b00000000, 0b00000000, 0b00000001},
po: limitPO(31),
},
} {
got := uint8(Proximity(base, tc.addr))
got := Proximity(base, tc.addr)
if got != tc.po {
t.Errorf("got %v bin, want %v", got, tc.po)
}
......
......@@ -13,11 +13,11 @@ import (
)
const (
SectionSize = 32
Branches = 128
ChunkSize = SectionSize * Branches
HashSize = 32
MaxPO = 16
SectionSize = 32
Branches = 128
ChunkSize = SectionSize * Branches
HashSize = 32
MaxPO uint8 = 15
)
// 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