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 all commits
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
48 changes: 44 additions & 4 deletions storage/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,12 @@ 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))
panic(fmt.Sprintf("storage NewNodeFromBitIntOld(): totalDepth mod 8: %v, want %v", got, want))
}

// TODO(al): We _could_ use Bits() and avoid the extra copy/alloc.
Expand All @@ -182,7 +182,7 @@ func NewNodeIDFromBigInt(depth int, index *big.Int, totalDepth int) NodeID {

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

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 {
panic(fmt.Sprintf("storage NewNodeFromBitInt(): totalDepth mod 8: %v, want %v", got, want))
}

if totalDepth == 0 {
panic("storage NewNodeFromBitInt(): totalDepth must not be zero")
}

// Put index in the LSB bits of path.
// This code more-or-less pinched from nat.go in the golang math/big package:
const _S = bits.UintSize / 8
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)
}