Commit df24f5b0 authored by Petar Maymounkov's avatar Petar Maymounkov

Change key object to use the same byte order as big.Int and kbucket.ID

parent 00bb09a2
......@@ -39,7 +39,7 @@ func randomTestTableHealthSubsetSamples(contactSize, knownSize int) *testTableHe
func randomKey(size int) key.Key {
k := make([]byte, size)
rand.Read(k)
return key.Key(k)
return key.BytesKey(k)
}
type testTableHealthSample struct {
......
......@@ -11,14 +11,21 @@ import (
kbucket "github.com/libp2p/go-libp2p-kbucket"
)
// TODO: Find a way to prohibit casting bytes to Key.
func KbucketIDToKey(id kbucket.ID) Key {
return Key(reverseBytesBits(id))
return Key(id)
}
// Key is a vector of bits backed by a Go byte slice in big endian byte order and big-endian bit order.
func ByteKey(b byte) Key {
return Key{b}
}
func BytesKey(b []byte) Key {
return Key(b)
}
// Key is a vector of bits backed by a Go byte slice.
// First byte is most significant.
// First bit in each byte is most significant.
// First bit (in each byte) is least significant.
type Key []byte
// reverseBytesBits reverses the bit-endianness of each byte in a slice.
......@@ -31,7 +38,7 @@ func reverseBytesBits(blob []byte) []byte {
}
func (k Key) BitAt(offset int) byte {
if k[offset/8]&(byte(1)<<(offset%8)) == 0 {
if k[offset/8]&(byte(1)<<(7-offset%8)) == 0 {
return 0
} else {
return 1
......@@ -39,7 +46,7 @@ func (k Key) BitAt(offset int) byte {
}
func (k Key) NormInt() *big.Int {
return big.NewInt(0).SetBytes(reverseBytesBits(k))
return big.NewInt(0).SetBytes(k)
}
func (k Key) BitLen() int {
......@@ -51,10 +58,11 @@ func (k Key) String() string {
return string(b)
}
// BitString returns a bit representation of the key, in descending order of significance.
func (k Key) BitString() string {
s := make([]string, len(k))
for i, b := range k {
s[len(k)-i-1] = fmt.Sprintf("%08b", b)
s[i] = fmt.Sprintf("%08b", b)
}
return strings.Join(s, "")
}
......@@ -64,7 +72,7 @@ func Equal(x, y Key) bool {
}
func Xor(x, y Key) Key {
z := make([]byte, len(x))
z := make(Key, len(x))
for i := range x {
z[i] = x[i] ^ y[i]
}
......
......@@ -35,13 +35,13 @@ func TestBitEndiannes(t *testing.T) {
func TestKeyString(t *testing.T) {
key := Key{0x05, 0xf0}
if key.BitString() != "1111000000000101" {
if key.BitString() != "0000010111110000" {
t.Errorf("unexpected bit string: %s", key.BitString())
}
}
func TestBitAt(t *testing.T) {
key := Key{0x21, 0x84}
key := Key{0x84, 0x21}
switch {
case key.BitAt(0) != 1:
t.Errorf("bit 0 flipped")
......
......@@ -58,8 +58,11 @@ type testAddSample struct {
}
var testAddSamples = []*testAddSample{
{Keys: []key.Key{{1}, {3}, {5}, {7}, {11}, {13}}},
{Keys: []key.Key{{11}, {22}, {23}, {25}, {27}, {28}, {31}, {32}, {33}}},
{Keys: []key.Key{key.ByteKey(1), key.ByteKey(3), key.ByteKey(5), key.ByteKey(7), key.ByteKey(11), key.ByteKey(13)}},
{Keys: []key.Key{
key.ByteKey(11), key.ByteKey(22), key.ByteKey(23), key.ByteKey(25),
key.ByteKey(27), key.ByteKey(28), key.ByteKey(31), key.ByteKey(32), key.ByteKey(33),
}},
}
func randomTestAddSamples(count int) []*testAddSample {
......@@ -73,9 +76,9 @@ func randomTestAddSamples(count int) []*testAddSample {
func randomTestAddSample(setSize, keySizeByte int) *testAddSample {
keySet := make([]key.Key, setSize)
for i := range keySet {
k := make(key.Key, keySizeByte)
k := make([]byte, keySizeByte)
rand.Read(k)
keySet[i] = k
keySet[i] = key.BytesKey(k)
}
return &testAddSample{
Keys: keySet,
......
......@@ -69,7 +69,7 @@ func setIntersect(left, right []key.Key) []key.Key {
func randomTestIntersectSample(leftSize, rightSize, intersectSize int) *testIntersectSample {
keys := make([]key.Key, leftSize+rightSize-intersectSize)
for i := range keys {
keys[i] = key.Key{byte(rand.Intn(256))}
keys[i] = key.ByteKey(byte(rand.Intn(256)))
}
return &testIntersectSample{
LeftKeys: keys[:leftSize],
......@@ -92,16 +92,16 @@ func testIntersectSampleFromJSON(srcJSON string) *testIntersectSample {
var testIntersectSamples = []*testIntersectSample{
{
LeftKeys: []key.Key{{1, 2, 3}},
RightKeys: []key.Key{{1, 3, 5}},
LeftKeys: []key.Key{key.ByteKey(1), key.ByteKey(2), key.ByteKey(3)},
RightKeys: []key.Key{key.ByteKey(1), key.ByteKey(3), key.ByteKey(5)},
},
{
LeftKeys: []key.Key{{1, 2, 3, 4, 5, 6}},
RightKeys: []key.Key{{3, 5, 7}},
LeftKeys: []key.Key{key.ByteKey(1), key.ByteKey(2), key.ByteKey(3), key.ByteKey(4), key.ByteKey(5), key.ByteKey(6)},
RightKeys: []key.Key{key.ByteKey(3), key.ByteKey(5), key.ByteKey(7)},
},
{
LeftKeys: []key.Key{{23, 3, 7, 13, 17}},
RightKeys: []key.Key{{2, 11, 17, 19, 23}},
LeftKeys: []key.Key{key.ByteKey(23), key.ByteKey(3), key.ByteKey(7), key.ByteKey(13), key.ByteKey(17)},
RightKeys: []key.Key{key.ByteKey(2), key.ByteKey(11), key.ByteKey(17), key.ByteKey(19), key.ByteKey(23)},
},
}
......
......@@ -14,15 +14,15 @@ func TestInsertRemove(t *testing.T) {
func testSeq(r *Trie, t *testing.T) {
for _, s := range testInsertSeq {
depth, _ := r.Add(key.Key(s.key))
depth, _ := r.Add(key.BytesKey(s.key))
if depth != s.insertedDepth {
t.Errorf("inserting expected %d, got %d", s.insertedDepth, depth)
t.Errorf("inserting expected depth %d, got %d", s.insertedDepth, depth)
}
}
for _, s := range testRemoveSeq {
depth, _ := r.Remove(key.Key(s.key))
depth, _ := r.Remove(key.BytesKey(s.key))
if depth != s.reachedDepth {
t.Errorf("removing expected %d, got %d", s.reachedDepth, depth)
t.Errorf("removing expected depth %d, got %d", s.reachedDepth, depth)
}
}
}
......@@ -31,20 +31,20 @@ var testInsertSeq = []struct {
key []byte
insertedDepth int
}{
{key: []byte{0x0}, insertedDepth: 0},
{key: []byte{0x1}, insertedDepth: 1},
{key: []byte{0x8}, insertedDepth: 4},
{key: []byte{0x3}, insertedDepth: 2},
{key: []byte{0x4}, insertedDepth: 3},
{key: []byte{0x00}, insertedDepth: 0},
{key: []byte{0x80}, insertedDepth: 1},
{key: []byte{0x10}, insertedDepth: 4},
{key: []byte{0xc0}, insertedDepth: 2},
{key: []byte{0x20}, insertedDepth: 3},
}
var testRemoveSeq = []struct {
key []byte
reachedDepth int
}{
{key: []byte{0x0}, reachedDepth: 4},
{key: []byte{0x8}, reachedDepth: 3},
{key: []byte{0x4}, reachedDepth: 1},
{key: []byte{0x1}, reachedDepth: 2},
{key: []byte{0x3}, reachedDepth: 0},
{key: []byte{0x00}, reachedDepth: 4},
{key: []byte{0x10}, reachedDepth: 3},
{key: []byte{0x20}, reachedDepth: 1},
{key: []byte{0x80}, reachedDepth: 2},
{key: []byte{0xc0}, reachedDepth: 0},
}
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