Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert directly from Int.Bits() to NodeID #1614

Merged
merged 2 commits into from
May 17, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions storage/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,10 @@ func NewNodeIDFromPrefix(prefix []byte, depth int, index int64, subDepth, totalD
}
}

// NewNodeIDFromBigInt returns a NodeID of a big.Int with no prefix.
// newNodeIDFromBigIntOld returns a NodeID of a big.Int with no prefix.
// index contains the path's least significant bits.
// depth indicates the number of bits from the most significant bit to treat as part of the path.
func NewNodeIDFromBigInt(depth int, index *big.Int, totalDepth int) NodeID {
func newNodeIDFromBigIntOld(depth int, index *big.Int, totalDepth int) NodeID {
if got, want := totalDepth%8, 0; got != want || got < want {
panic(fmt.Sprintf("storage NewNodeFromBitInt(): totalDepth mod 8: %v, want %v", got, want))
RJPercival marked this conversation as resolved.
Show resolved Hide resolved
}
Expand All @@ -192,6 +192,46 @@ func NewNodeIDFromBigInt(depth int, index *big.Int, totalDepth int) NodeID {
}
}

func NewNodeIDFromBigInt(depth int, index *big.Int, totalDepth int) NodeID {
if got, want := totalDepth%8, 0; got != want || got < want {
RJPercival marked this conversation as resolved.
Show resolved Hide resolved
panic(fmt.Sprintf("storage NewNodeFromBitInt(): totalDepth mod 8: %v, want %v", got, want))
}

if totalDepth == 0 {
panic("totalDepth must not be zero")
RJPercival marked this conversation as resolved.
Show resolved Hide resolved
}

// Put index in the LSB bits of path.
// This code more-or-less pinched from nat.go in the golang math/big package:
_S := bits.UintSize / 8
RJPercival marked this conversation as resolved.
Show resolved Hide resolved
path := make([]byte, totalDepth/8)

iBits := index.Bits()
i := len(path)
loop:
for _, d := range iBits {
for j := 0; j < _S; j++ {
i--
if i < 0 {
break loop
}
path[i] = byte(d)
d >>= 8
}
}

// TODO(gdbelvin): consider masking off insignificant bits past depth.
if glog.V(5) {
glog.Infof("NewNodeIDFromBigInt(%v, %x, %v): %v, %x",
depth, index, totalDepth, depth, path)
}

return NodeID{
Path: path,
PrefixLenBits: depth,
}
}

// BigInt returns the big.Int for this node.
func (n NodeID) BigInt() *big.Int {
return new(big.Int).SetBytes(n.Path)
Expand Down
19 changes: 17 additions & 2 deletions storage/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func TestNewNodeIDFromBigInt(t *testing.T) {
// We should be able to get the same big.Int back. This is used in
// the HStar2 implementation so should be tested.
if got, want := n.BigInt(), tc.index; want.Cmp(got) != 0 {
t.Errorf("NewNodeIDFromBigInt(%v, %x, %v): got: %v, want: %v",
t.Errorf("NewNodeIDFromBigInt(%v, %x, %v):got:\n%v, want:\n%v",
tc.depth, tc.index.Bytes(), tc.totalDepth, got, want)
}
}
Expand All @@ -201,7 +201,7 @@ func TestNewNodeIDFromBigIntPanic(t *testing.T) {
defer func() {
got := recover()
if (got != nil && !want) || (got == nil && want) {
t.Errorf("Incorrect panic behaviour got: %v, want: %v", got, want)
t.Errorf("Incorrect panic behaviour (b=%d) got: %v, want: %v", b, got, want)
}
}()
_ = NewNodeIDFromBigInt(12, big.NewInt(234), b)
Expand Down Expand Up @@ -892,3 +892,18 @@ func BenchmarkSuffix(b *testing.B) {
_ = n.Suffix(10, 176)
}
}

func runBenchmarkNewNodeIDFromBigInt(b *testing.B, f func(int, *big.Int, int) NodeID) {
b.Helper()
for i := 0; i < b.N; i++ {
_ = f(256, new(big.Int).SetBytes(h2b("00")), 256)
}
}

func BenchmarkNewNodeIDFromBigIntOld(b *testing.B) {
runBenchmarkNewNodeIDFromBigInt(b, newNodeIDFromBigIntOld)
}

func BenchmarkNewNodeIDFromBigIntNew(b *testing.B) {
runBenchmarkNewNodeIDFromBigInt(b, NewNodeIDFromBigInt)
}