// Distance returns the distance metric in this key space func (s *xorKeySpace) Distance(k1, k2 Key) *big.Int { // XOR the keys k3 := u.XOR(k1.Bytes, k2.Bytes) // interpret it as an integer dist := big.NewInt(0).SetBytes(k3) return dist }
// ID returns the ID of a given Conn. func ID(c Conn) string { l := fmt.Sprintf("%s/%s", c.LocalMultiaddr(), c.LocalPeer().ID()) r := fmt.Sprintf("%s/%s", c.RemoteMultiaddr(), c.RemotePeer().ID()) lh := u.Hash([]byte(l)) rh := u.Hash([]byte(r)) ch := u.XOR(lh, rh) return u.Key(ch).Pretty() }
// ID is an identifier unique to this connection. // In MultiConn, this is all the children IDs XORed together. func (c *MultiConn) ID() string { c.RLock() defer c.RUnlock() ids := []byte(nil) for i := range c.conns { if ids == nil { ids = []byte(i) } else { ids = u.XOR(ids, []byte(i)) } } return string(ids) }
func TestDistancesAndCenterSorting(t *testing.T) { adjs := [][]byte{ []byte{173, 149, 19, 27, 192, 183, 153, 192, 177, 175, 71, 127, 177, 79, 207, 38, 166, 169, 247, 96, 121, 228, 139, 240, 144, 172, 183, 232, 54, 123, 253, 14}, []byte{223, 63, 97, 152, 4, 169, 47, 219, 64, 87, 25, 45, 196, 61, 215, 72, 234, 119, 138, 220, 82, 188, 73, 140, 232, 5, 36, 192, 20, 184, 17, 25}, []byte{73, 176, 221, 176, 149, 143, 22, 42, 129, 124, 213, 114, 232, 95, 189, 154, 18, 3, 122, 132, 32, 199, 53, 185, 58, 157, 117, 78, 52, 146, 157, 127}, []byte{73, 176, 221, 176, 149, 143, 22, 42, 129, 124, 213, 114, 232, 95, 189, 154, 18, 3, 122, 132, 32, 199, 53, 185, 58, 157, 117, 78, 52, 146, 157, 127}, []byte{73, 176, 221, 176, 149, 143, 22, 42, 129, 124, 213, 114, 232, 95, 189, 154, 18, 3, 122, 132, 32, 199, 53, 185, 58, 157, 117, 78, 52, 146, 157, 126}, []byte{73, 0, 221, 176, 149, 143, 22, 42, 129, 124, 213, 114, 232, 95, 189, 154, 18, 3, 122, 132, 32, 199, 53, 185, 58, 157, 117, 78, 52, 146, 157, 127}, } keys := make([]Key, len(adjs)) for i, a := range adjs { keys[i] = Key{Space: XORKeySpace, Bytes: a} } cmp := func(a int64, b *big.Int) int { return big.NewInt(a).Cmp(b) } if 0 != cmp(0, keys[2].Distance(keys[3])) { t.Errorf("distance calculation wrong: %v", keys[2].Distance(keys[3])) } if 0 != cmp(1, keys[2].Distance(keys[4])) { t.Errorf("distance calculation wrong: %v", keys[2].Distance(keys[4])) } d1 := keys[2].Distance(keys[5]) d2 := u.XOR(keys[2].Bytes, keys[5].Bytes) d2 = d2[len(keys[2].Bytes)-len(d1.Bytes()):] // skip empty space for big if !bytes.Equal(d1.Bytes(), d2) { t.Errorf("bytes should be the same. %v == %v", d1.Bytes(), d2) } if -1 != cmp(2<<32, keys[2].Distance(keys[5])) { t.Errorf("2<<32 should be smaller") } keys2 := SortByDistance(XORKeySpace, keys[2], keys) order := []int{2, 3, 4, 5, 1, 0} for i, o := range order { if !bytes.Equal(keys[o].Bytes, keys2[i].Bytes) { t.Errorf("order is wrong. %d?? %v == %v", o, keys[o], keys2[i]) } } }
func commonPrefixLen(a, b ID) int { return ks.ZeroPrefixLen(u.XOR(a, b)) }
func xor(a, b ID) ID { return ID(u.XOR(a, b)) }