Skip to content

Commit

Permalink
Custom bitfield type for custom serialization/deserialization
Browse files Browse the repository at this point in the history
Without touching the generated code. This is a slightly breaking change,
but it shouldn't affect anyone.
  • Loading branch information
Stebalien authored and rvagg committed Aug 5, 2024
1 parent 361416e commit dcdad8e
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 52 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ test:
go test ./...
.PHONY: test

gen:
go run ./gen
.PHONY: gen

coverage:
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
Expand Down
26 changes: 26 additions & 0 deletions bitfield.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package hamt

import (
"io"
"math/big"

cbg "github.com/whyrusleeping/cbor-gen"
)

type Bitfield struct {
big.Int
}

func (b *Bitfield) MarshalCBOR(w io.Writer) error {
return cbg.WriteByteArray(w, b.Bytes())
}

func (b *Bitfield) UnmarshalCBOR(r io.Reader) error {
bytes, err := cbg.ReadByteArray(r, cbg.ByteArrayMaxLen)
if err != nil {
return err
}
b.SetBytes(bytes)

return nil
}
86 changes: 41 additions & 45 deletions cbor_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 4 additions & 6 deletions hamt.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"context"
"fmt"
"math/big"
"sort"

cid "github.com/ipfs/go-cid"
Expand Down Expand Up @@ -81,7 +80,7 @@ type HashFunc func([]byte) []byte
// pointers [Pointer]
// } representation tuple
type Node struct {
Bitfield *big.Int
Bitfield Bitfield
Pointers []*Pointer

bitWidth int
Expand Down Expand Up @@ -237,7 +236,6 @@ func (n *Node) Delete(ctx context.Context, k string) (bool, error) {
// Constructs a new node value.
func newNode(cs cbor.IpldStore, hashFn HashFunc, bitWidth int) *Node {
nd := &Node{
Bitfield: big.NewInt(0),
Pointers: make([]*Pointer, 0),
bitWidth: bitWidth,
hash: hashFn,
Expand Down Expand Up @@ -776,7 +774,7 @@ func (n *Node) modifyValue(ctx context.Context, hv *hashBits, k []byte, v *cbg.D
// bucket containing the single key/value pair at that position.
func (n *Node) insertKV(idx int, k []byte, v *cbg.Deferred) error {
i := n.indexForBitPos(idx)
n.Bitfield.SetBit(n.Bitfield, idx, 1)
n.Bitfield.SetBit(&n.Bitfield.Int, idx, 1)

p := &Pointer{KVs: []*KV{{Key: k, Value: v}}}

Expand All @@ -798,7 +796,7 @@ func (n *Node) setPointer(i byte, p *Pointer) error {
func (n *Node) rmPointer(i byte, idx int) error {
copy(n.Pointers[i:], n.Pointers[i+1:])
n.Pointers = n.Pointers[:len(n.Pointers)-1]
n.Bitfield.SetBit(n.Bitfield, idx, 0)
n.Bitfield.SetBit(&n.Bitfield.Int, idx, 0)

return nil
}
Expand All @@ -824,7 +822,7 @@ func (n *Node) getPointer(i byte) *Pointer {
func (n *Node) Copy() *Node {
// TODO(rvagg): clarify what situations this method is actually useful for.
nn := newNode(n.store, n.hash, n.bitWidth)
nn.Bitfield.Set(n.Bitfield)
nn.Bitfield.Set(&n.Bitfield.Int)
nn.Pointers = make([]*Pointer, len(n.Pointers))

for i, p := range n.Pointers {
Expand Down
2 changes: 1 addition & 1 deletion uhamt.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
// associated array. Indexes `[1]` and `[2]` are not present, but index `[3]`
// is at the second position of our Pointers array.
func (n *Node) indexForBitPos(bp int) int {
return indexForBitPos(bp, n.Bitfield)
return indexForBitPos(bp, &n.Bitfield.Int)
}

func indexForBitPos(bp int, bitfield *big.Int) int {
Expand Down

0 comments on commit dcdad8e

Please sign in to comment.