table.go 1.31 KB
Newer Older
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
1 2 3
package dht

import (
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
4 5
	"bytes"
	"container/list"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
6 7 8 9 10
)

// ID for IpfsDHT should be a byte slice, to allow for simpler operations
// (xor). DHT ids are based on the peer.IDs.
//
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
11 12
// NOTE: peer.IDs are biased because they are multihashes (first bytes
// biased). Thus, may need to re-hash keys (uniform dist). TODO(jbenet)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
13 14 15 16 17 18 19 20
type ID []byte

// Bucket holds a list of peers.
type Bucket []*list.List

// RoutingTable defines the routing table.
type RoutingTable struct {

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
21 22
	// kBuckets define all the fingers to other nodes.
	Buckets []Bucket
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
23 24
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
25 26 27 28 29 30 31 32 33 34 35 36 37
func (id ID) Equal(other ID) bool {
	return bytes.Equal(id, other)
}

func (id ID) Less(other interface{}) bool {
	a, b := equalizeSizes(id, other.(ID))
	for i := 0; i < len(a); i++ {
		if a[i] != b[i] {
			return a[i] < b[i]
		}
	}
	return len(a) < len(b)
}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
38 39

func (id ID) commonPrefixLen() int {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
40 41 42 43 44 45 46 47
	for i := 0; i < len(id); i++ {
		for j := 0; j < 8; j++ {
			if (id[i]>>uint8(7-j))&0x1 != 0 {
				return i*8 + j
			}
		}
	}
	return len(id)*8 - 1
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
48 49 50
}

func xor(a, b ID) ID {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
	a, b = equalizeSizes(a, b)

	c := make(ID, len(a))
	for i := 0; i < len(a); i++ {
		c[i] = a[i] ^ b[i]
	}
	return c
}

func equalizeSizes(a, b ID) (ID, ID) {
	la := len(a)
	lb := len(b)

	if la < lb {
		na := make([]byte, lb)
		copy(na, a)
		a = na
	} else if lb < la {
		nb := make([]byte, la)
		copy(nb, b)
		b = nb
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
73

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
74
	return a, b
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
75
}