From d6a7592e58a4e102aa53861a7e2e964a4adebd30 Mon Sep 17 00:00:00 2001 From: Will Scott Date: Sun, 15 Nov 2020 12:06:14 -0800 Subject: [PATCH 1/7] make hamt a go-ipld-prime ipld.Node --- hamt.go | 21 ++++-- hamt_test.go | 6 +- ipld.go | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+), 8 deletions(-) create mode 100644 ipld.go diff --git a/hamt.go b/hamt.go index 19551d9..0f837fd 100644 --- a/hamt.go +++ b/hamt.go @@ -9,6 +9,7 @@ import ( cid "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" + "github.com/ipld/go-ipld-prime" cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" ) @@ -78,6 +79,7 @@ type Node struct { // for fetching and storing children store cbor.IpldStore + proto ipld.NodePrototype } // Pointer is an element in a HAMT node's Pointers array, encoded as an IPLD @@ -178,6 +180,14 @@ func UseHashFunction(hash func([]byte) []byte) Option { } } +// WithPrototype sets the ipld Prototype for the Hamt Node, to support +// the use of the ipld MapIterator reconstruction of values. +func WithPrototype(proto ipld.NodePrototype) Option { + return func(nd *Node) { + nd.proto = proto + } +} + //----------------------------------------------------------------------------- // Instance and helpers functions @@ -282,7 +292,7 @@ func (n *Node) getValue(ctx context.Context, hv *hashBits, k string, cb func(*KV if c.isShard() { // if isShard, we have a pointer to a child that we need to load and // delegate our find operation to - chnd, err := c.loadChild(ctx, n.store, n.bitWidth, n.hash) + chnd, err := c.loadChild(ctx, n.store, n.bitWidth, n.hash, n.proto) if err != nil { return err } @@ -304,7 +314,7 @@ func (n *Node) getValue(ctx context.Context, hv *hashBits, k string, cb func(*KV // load a HAMT node from the IpldStore and pass on the (assumed) parameters // that are not stored with the node. -func (p *Pointer) loadChild(ctx context.Context, ns cbor.IpldStore, bitWidth int, hash func([]byte) []byte) (*Node, error) { +func (p *Pointer) loadChild(ctx context.Context, ns cbor.IpldStore, bitWidth int, hash func([]byte) []byte, proto ipld.NodePrototype) (*Node, error) { if p.cache != nil { return p.cache, nil } @@ -313,6 +323,7 @@ func (p *Pointer) loadChild(ctx context.Context, ns cbor.IpldStore, bitWidth int if err != nil { return nil, err } + out.proto = proto p.cache = out return out, nil @@ -430,7 +441,7 @@ func (n *Node) checkSize(ctx context.Context) (uint64, error) { totsize := uint64(len(def.Raw)) for _, ch := range n.Pointers { if ch.isShard() { - chnd, err := ch.loadChild(ctx, n.store, n.bitWidth, n.hash) + chnd, err := ch.loadChild(ctx, n.store, n.bitWidth, n.hash, n.proto) if err != nil { return 0, err } @@ -604,7 +615,7 @@ func (n *Node) modifyValue(ctx context.Context, hv *hashBits, k []byte, v *cbg.D if child.isShard() { // if isShard, we have a pointer to a child that we need to load and // delegate our modify operation to - chnd, err := child.loadChild(ctx, n.store, n.bitWidth, n.hash) + chnd, err := child.loadChild(ctx, n.store, n.bitWidth, n.hash, n.proto) if err != nil { return err } @@ -795,7 +806,7 @@ func (p *Pointer) isShard() bool { func (n *Node) ForEach(ctx context.Context, f func(k string, val interface{}) error) error { for _, p := range n.Pointers { if p.isShard() { - chnd, err := p.loadChild(ctx, n.store, n.bitWidth, n.hash) + chnd, err := p.loadChild(ctx, n.store, n.bitWidth, n.hash, n.proto) if err != nil { return err } diff --git a/hamt_test.go b/hamt_test.go index 96ab867..c19db04 100644 --- a/hamt_test.go +++ b/hamt_test.go @@ -448,7 +448,7 @@ func printHamt(hamt *Node) { fmt.Printf("%s‣ %v:\n", strings.Repeat(" ", depth), c) for _, p := range n.Pointers { if p.isShard() { - child, err := p.loadChild(ctx, n.store, n.bitWidth, n.hash) + child, err := p.loadChild(ctx, n.store, n.bitWidth, n.hash, n.proto) if err != nil { panic(err) } @@ -472,7 +472,7 @@ func dotGraphRec(n *Node, name *int) { if p.isShard() { *name++ fmt.Printf("\tn%d -> n%d;\n", cur, *name) - nd, err := p.loadChild(context.Background(), n.store, n.bitWidth, n.hash) + nd, err := p.loadChild(context.Background(), n.store, n.bitWidth, n.hash, n.proto) if err != nil { panic(err) } @@ -508,7 +508,7 @@ func statsrec(n *Node, st *hamtStats) { st.totalNodes++ for _, p := range n.Pointers { if p.isShard() { - nd, err := p.loadChild(context.Background(), n.store, n.bitWidth, n.hash) + nd, err := p.loadChild(context.Background(), n.store, n.bitWidth, n.hash, n.proto) if err != nil { panic(err) } diff --git a/ipld.go b/ipld.go new file mode 100644 index 0000000..f882313 --- /dev/null +++ b/ipld.go @@ -0,0 +1,197 @@ +package hamt + +import ( + "bytes" + "context" + + "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/codec/dagcbor" +) + +var _ ipld.Node = (*Node)(nil) + +func (n *Node) AsBool() (bool, error) { + return false, ErrNotFound +} + +func (n *Node) AsBytes() ([]byte, error) { + return nil, ErrNotFound +} + +func (n *Node) AsString() (string, error) { + return "", ErrNotFound +} + +func (n *Node) AsInt() (int, error) { + return 0, ErrNotFound +} + +func (n *Node) AsFloat() (float64, error) { + return 0.0, ErrNotFound +} + +func (n *Node) AsLink() (ipld.Link, error) { + return nil, ErrNotFound +} + +func (n *Node) IsAbsent() bool { + return false +} + +func (n *Node) IsNull() bool { + return n.Bitfield == nil +} + +func (n *Node) Length() int { + l := 0 + for _, p := range n.Pointers { + if p.Link.Defined() { + c, err := p.loadChild(context.Background(), n.store, n.bitWidth, n.hash, n.proto) + if err != nil { + return -1 + } + l += c.Length() + } else { + l += len(p.KVs) + } + } + return l +} + +func (n *Node) ReprKind() ipld.ReprKind { + return ipld.ReprKind_Map +} + +// LookupByString looks up a child object in this node and returns it. +// The returned Node may be any of the ReprKind: +// a primitive (string, int, etc), a map, a list, or a link. +// +// If the Kind of this Node is not ReprKind_Map, a nil node and an error +// will be returned. +// +// If the key does not exist, a nil node and an error will be returned. +func (n *Node) LookupByString(key string) (ipld.Node, error) { + data, err := n.FindRaw(context.Background(), key) + if err != nil { + return nil, err + } + _, val, err := n.realize(key, data) + return val, err +} + +func (n *Node) LookupByNode(key ipld.Node) (ipld.Node, error) { + if key.ReprKind() == ipld.ReprKind_String { + s, e := key.AsString() + if e != nil { + return nil, e + } + return n.LookupByString(s) + } else if key.ReprKind() == ipld.ReprKind_Bytes { + b, e := key.AsBytes() + if e != nil { + return nil, e + } + return n.LookupByString(string(b)) + } + return nil, ipld.ErrInvalidKey{} +} + +func (n *Node) LookupByIndex(idx int) (ipld.Node, error) { + return nil, ErrNotFound +} + +func (n *Node) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + return n.LookupByString(seg.String()) +} + +// MapIterator returns an iterator which yields key-value pairs +// traversing the node. +// If the node kind is anything other than a map, nil will be returned. +// +// The iterator will yield every entry in the map; that is, it +// can be expected that itr.Next will be called node.Length times +// before itr.Done becomes true. +func (n *Node) MapIterator() ipld.MapIterator { + mi := &hmi{ + at: n, + ukv: make([]*KV, 0), + up: n.Pointers, + } + return mi +} + +type hmi struct { + at *Node + ukv []*KV + up []*Pointer + err error +} + +func (mi *hmi) Done() bool { + if len(mi.ukv) == 0 && len(mi.up) == 0 { + return true + } + if len(mi.ukv) > 0 { + return false + } + mi.loadNext() + return mi.Done() +} + +func (mi *hmi) loadNext() { + p := mi.up[0] + mi.up = mi.up[1:] + if p.isShard() { + chld, err := p.loadChild(context.Background(), mi.at.store, mi.at.bitWidth, mi.at.hash, mi.at.proto) + if err != nil { + mi.err = err + return + } + mi.up = append(mi.up, chld.Pointers...) + } else { + mi.ukv = append(mi.ukv, p.KVs...) + } +} + +func (mi *hmi) Next() (ipld.Node, ipld.Node, error) { + if mi.err != nil { + return nil, nil, mi.err + } + // If false, we've ensured at least one entry in mi.ukv + if mi.Done() { + return nil, nil, mi.err + } + + kv := mi.ukv[0] + mi.ukv = mi.ukv[1:] + return mi.at.realize(string(kv.Key), kv.Value.Raw) +} + +func (n *Node) realize(key string, value []byte) (ipld.Node, ipld.Node, error) { + ma, err := n.proto.NewBuilder().BeginMap(0) + if err != nil { + return nil, nil, err + } + + mak := ma.KeyPrototype() + mav := ma.ValuePrototype(key) + + keyBuilder := mak.NewBuilder() + if err := keyBuilder.AssignString(key); err != nil { + return nil, nil, err + } + + valueBuilder := mav.NewBuilder() + if err := dagcbor.Decoder(valueBuilder, bytes.NewBuffer(value)); err != nil { + return nil, nil, err + } + return keyBuilder.Build(), valueBuilder.Build(), nil +} + +func (n *Node) ListIterator() ipld.ListIterator { + return nil +} + +func (n *Node) Prototype() ipld.NodePrototype { + return n.proto +} From 38d62e432eed9d5333af22e37853f1f1b588bd9d Mon Sep 17 00:00:00 2001 From: Will Scott Date: Sun, 15 Nov 2020 15:35:21 -0800 Subject: [PATCH 2/7] add prototype/degraded builder --- ipld.go | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/ipld.go b/ipld.go index f882313..525ea7f 100644 --- a/ipld.go +++ b/ipld.go @@ -195,3 +195,94 @@ func (n *Node) ListIterator() ipld.ListIterator { func (n *Node) Prototype() ipld.NodePrototype { return n.proto } + +func NewTypedHamt(key ipld.NodePrototype, value ipld.NodePrototype) ipld.NodePrototype { + return &hamtProto{key, value} +} + +type hamtProto struct { + k ipld.NodePrototype + v ipld.NodePrototype +} + +func (h *hamtProto) NewBuilder() ipld.NodeBuilder { + return &hamtBuilder{h, nil} +} + +type hamtBuilder struct { + proto *hamtProto + + n *Node +} + +func (h *hamtBuilder) Build() ipld.Node { + return h.n +} + +func (h *hamtBuilder) Reset() { + h.n = nil +} + +func (h *hamtBuilder) BeginMap(sizeHint int) (ipld.MapAssembler, error) { + return h, nil +} + +func (h *hamtBuilder) AssembleKey() ipld.NodeAssembler { + return nil +} + +func (h *hamtBuilder) AssembleValue() ipld.NodeAssembler { + return nil +} + +func (h *hamtBuilder) AssembleEntry(k string) (ipld.NodeAssembler, error) { + return nil, nil +} + +func (h *hamtBuilder) Finish() error { + return nil +} +func (h *hamtBuilder) KeyPrototype() ipld.NodePrototype { + return h.proto.k +} +func (h *hamtBuilder) ValuePrototype(k string) ipld.NodePrototype { + return h.proto.v +} + +func (h *hamtBuilder) BeginList(sizeHint int) (ipld.ListAssembler, error) { + return nil, ErrNotFound +} +func (h *hamtBuilder) AssignNull() error { + return ErrNotFound +} +func (h *hamtBuilder) AssignBool(bool) error { + return ErrNotFound +} +func (h *hamtBuilder) AssignInt(int) error { + return ErrNotFound +} +func (h *hamtBuilder) AssignFloat(float64) error { + return ErrNotFound +} +func (h *hamtBuilder) AssignString(string) error { + return ErrNotFound +} +func (h *hamtBuilder) AssignBytes([]byte) error { + return ErrNotFound +} +func (h *hamtBuilder) AssignLink(ipld.Link) error { + return ErrNotFound +} + +func (h *hamtBuilder) AssignNode(n ipld.Node) error { + hn, ok := n.(*Node) + if !ok { + return ErrMalformedHamt + } + h.n = hn + return nil +} + +func (h *hamtBuilder) Prototype() ipld.NodePrototype { + return h.proto +} From 6d6dfa9b3960861f59b4161f78ec0fa49783be57 Mon Sep 17 00:00:00 2001 From: Will Scott Date: Wed, 24 Feb 2021 19:43:44 -0800 Subject: [PATCH 3/7] update for new ipld-prime --- go.mod | 1 + go.sum | 16 ++++++++++++++++ ipld.go | 26 +++++++++++++------------- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 05bf042..d7958f1 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ require ( github.com/ipfs/go-block-format v0.0.2 github.com/ipfs/go-cid v0.0.6 github.com/ipfs/go-ipld-cbor v0.0.4 + github.com/ipld/go-ipld-prime v0.7.0 github.com/spaolacci/murmur3 v1.1.0 github.com/stretchr/testify v1.6.1 github.com/whyrusleeping/cbor-gen v0.0.0-20200806213330-63aa96ca5488 diff --git a/go.sum b/go.sum index 4132630..186d506 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,7 @@ github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJ github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3 h1:UIAh32wymBpStoe83YCzwVQQ5Oy/H0FdxvUS6DJDzms= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.6 h1:go0y+GcDOGeJIV01FeBsta4FHngoA4Wz7KMeLkXAhMs= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= @@ -20,14 +21,19 @@ github.com/ipfs/go-ipld-cbor v0.0.4 h1:Aw3KPOKXjvrm6VjwJvFf1F1ekR/BH3jdof3Bk7OTi github.com/ipfs/go-ipld-cbor v0.0.4/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= github.com/ipfs/go-ipld-format v0.0.1 h1:HCu4eB/Gh+KD/Q0M8u888RFkorTWNIL3da4oc5dwc80= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +github.com/ipld/go-ipld-prime v0.7.0 h1:eigF1ZpaL1prbsKYVMqPLoPJqD/pzkQOe2j1uzvVg7w= +github.com/ipld/go-ipld-prime v0.7.0/go.mod h1:0xEgdD6MKbZ1vF0GC+YcR/C4SQCAlRuOjIJ2i0HxqzM= github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771 h1:MHkK1uRtFbVqvAgvWxafZe54+5uBxLluGylDiKgdhwo= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= +github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= @@ -54,10 +60,13 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992 h1:bzMe+2coZJYHnhGgVlcQKuRy4FSny4ds8dLQjw5P1XE= github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1 h1:CskT+S6Ay54OwxBGB0R3Rsx4Muto6UnEYTyKJbyRIAI= +github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa h1:E+gaaifzi2xF65PbDmuKI3PhLWY6G5opMLniFq8vmXA= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= @@ -66,6 +75,7 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436 h1:qOpVTI+BrstcjTZLm2Yz/3sOnqkzj3FQoh0g+E5s3Gc= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158 h1:WXhVOwj2USAXB5oMDwRl3piOux2XMV9TANaYxXHdkoE= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200806213330-63aa96ca5488 h1:P/Q9QT99FpyHtFke7ERUqX7yYtZ/KigO880L+TKFyTQ= @@ -75,6 +85,9 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg= +golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -82,7 +95,10 @@ golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/ipld.go b/ipld.go index 525ea7f..b281b40 100644 --- a/ipld.go +++ b/ipld.go @@ -22,7 +22,7 @@ func (n *Node) AsString() (string, error) { return "", ErrNotFound } -func (n *Node) AsInt() (int, error) { +func (n *Node) AsInt() (int64, error) { return 0, ErrNotFound } @@ -42,8 +42,8 @@ func (n *Node) IsNull() bool { return n.Bitfield == nil } -func (n *Node) Length() int { - l := 0 +func (n *Node) Length() int64 { + l := int64(0) for _, p := range n.Pointers { if p.Link.Defined() { c, err := p.loadChild(context.Background(), n.store, n.bitWidth, n.hash, n.proto) @@ -52,14 +52,14 @@ func (n *Node) Length() int { } l += c.Length() } else { - l += len(p.KVs) + l += int64(len(p.KVs)) } } - return l + return int64(l) } -func (n *Node) ReprKind() ipld.ReprKind { - return ipld.ReprKind_Map +func (n *Node) Kind() ipld.Kind { + return ipld.Kind_Map } // LookupByString looks up a child object in this node and returns it. @@ -80,13 +80,13 @@ func (n *Node) LookupByString(key string) (ipld.Node, error) { } func (n *Node) LookupByNode(key ipld.Node) (ipld.Node, error) { - if key.ReprKind() == ipld.ReprKind_String { + if key.Kind() == ipld.Kind_String { s, e := key.AsString() if e != nil { return nil, e } return n.LookupByString(s) - } else if key.ReprKind() == ipld.ReprKind_Bytes { + } else if key.Kind() == ipld.Kind_Bytes { b, e := key.AsBytes() if e != nil { return nil, e @@ -96,7 +96,7 @@ func (n *Node) LookupByNode(key ipld.Node) (ipld.Node, error) { return nil, ipld.ErrInvalidKey{} } -func (n *Node) LookupByIndex(idx int) (ipld.Node, error) { +func (n *Node) LookupByIndex(idx int64) (ipld.Node, error) { return nil, ErrNotFound } @@ -223,7 +223,7 @@ func (h *hamtBuilder) Reset() { h.n = nil } -func (h *hamtBuilder) BeginMap(sizeHint int) (ipld.MapAssembler, error) { +func (h *hamtBuilder) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { return h, nil } @@ -249,7 +249,7 @@ func (h *hamtBuilder) ValuePrototype(k string) ipld.NodePrototype { return h.proto.v } -func (h *hamtBuilder) BeginList(sizeHint int) (ipld.ListAssembler, error) { +func (h *hamtBuilder) BeginList(sizeHint int64) (ipld.ListAssembler, error) { return nil, ErrNotFound } func (h *hamtBuilder) AssignNull() error { @@ -258,7 +258,7 @@ func (h *hamtBuilder) AssignNull() error { func (h *hamtBuilder) AssignBool(bool) error { return ErrNotFound } -func (h *hamtBuilder) AssignInt(int) error { +func (h *hamtBuilder) AssignInt(int64) error { return ErrNotFound } func (h *hamtBuilder) AssignFloat(float64) error { From 202c9a6a5241e177b6b92df0de98604a03707544 Mon Sep 17 00:00:00 2001 From: Will Scott Date: Wed, 20 Oct 2021 13:11:45 -0700 Subject: [PATCH 4/7] update for newer ipld-prime --- go.mod | 2 +- go.sum | 70 +++++++++++++++++++++++++++++---------------------------- ipld.go | 2 +- 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/go.mod b/go.mod index d7958f1..2a02ee0 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ require ( github.com/ipfs/go-block-format v0.0.2 github.com/ipfs/go-cid v0.0.6 github.com/ipfs/go-ipld-cbor v0.0.4 - github.com/ipld/go-ipld-prime v0.7.0 + github.com/ipld/go-ipld-prime v0.12.3 github.com/spaolacci/murmur3 v1.1.0 github.com/stretchr/testify v1.6.1 github.com/whyrusleeping/cbor-gen v0.0.0-20200806213330-63aa96ca5488 diff --git a/go.sum b/go.sum index 186d506..ab4ce71 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +1,17 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= -github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= -github.com/ipfs/go-cid v0.0.3 h1:UIAh32wymBpStoe83YCzwVQQ5Oy/H0FdxvUS6DJDzms= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.6 h1:go0y+GcDOGeJIV01FeBsta4FHngoA4Wz7KMeLkXAhMs= @@ -21,82 +22,83 @@ github.com/ipfs/go-ipld-cbor v0.0.4 h1:Aw3KPOKXjvrm6VjwJvFf1F1ekR/BH3jdof3Bk7OTi github.com/ipfs/go-ipld-cbor v0.0.4/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= github.com/ipfs/go-ipld-format v0.0.1 h1:HCu4eB/Gh+KD/Q0M8u888RFkorTWNIL3da4oc5dwc80= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= -github.com/ipld/go-ipld-prime v0.7.0 h1:eigF1ZpaL1prbsKYVMqPLoPJqD/pzkQOe2j1uzvVg7w= -github.com/ipld/go-ipld-prime v0.7.0/go.mod h1:0xEgdD6MKbZ1vF0GC+YcR/C4SQCAlRuOjIJ2i0HxqzM= -github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= +github.com/ipld/go-ipld-prime v0.12.3 h1:furVobw7UBLQZwlEwfE26tYORy3PAK8VYSgZOSr3JMQ= +github.com/ipld/go-ipld-prime v0.12.3/go.mod h1:PaeLYq8k6dJLmDUSLrzkEpoGV4PEfe/1OtFN/eALOc8= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/klauspost/cpuid/v2 v2.0.4 h1:g0I61F2K2DjRHz1cnxlkNSBIaePVoJIjjnHui8QHbiw= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= -github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771 h1:MHkK1uRtFbVqvAgvWxafZe54+5uBxLluGylDiKgdhwo= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= -github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= -github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= -github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= -github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multicodec v0.3.0 h1:tstDwfIjiHbnIjeM5Lp+pMrSeN+LCMsEwOrkPmWm03A= +github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= -github.com/multiformats/go-multihash v0.0.10 h1:lMoNbh2Ssd9PUF74Nz008KGzGPlfeV6wH3rit5IIGCM= github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg= +github.com/multiformats/go-multihash v0.0.15 h1:hWOPdrNqDjwHDx82vsYGSDZNyktOJJ2dzZJzFkOV1jM= +github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= +github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992 h1:bzMe+2coZJYHnhGgVlcQKuRy4FSny4ds8dLQjw5P1XE= github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1 h1:CskT+S6Ay54OwxBGB0R3Rsx4Muto6UnEYTyKJbyRIAI= -github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls= +github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa h1:E+gaaifzi2xF65PbDmuKI3PhLWY6G5opMLniFq8vmXA= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436 h1:qOpVTI+BrstcjTZLm2Yz/3sOnqkzj3FQoh0g+E5s3Gc= +github.com/warpfork/go-testmark v0.3.0 h1:Q81c4u7hT+BR5kNfNQhEF0VT2pmL7+Kk0wD+ORYl7iA= +github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158 h1:WXhVOwj2USAXB5oMDwRl3piOux2XMV9TANaYxXHdkoE= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200806213330-63aa96ca5488 h1:P/Q9QT99FpyHtFke7ERUqX7yYtZ/KigO880L+TKFyTQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200806213330-63aa96ca5488/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= -golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg= -golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= diff --git a/ipld.go b/ipld.go index b281b40..7837bef 100644 --- a/ipld.go +++ b/ipld.go @@ -182,7 +182,7 @@ func (n *Node) realize(key string, value []byte) (ipld.Node, ipld.Node, error) { } valueBuilder := mav.NewBuilder() - if err := dagcbor.Decoder(valueBuilder, bytes.NewBuffer(value)); err != nil { + if err := dagcbor.Decode(valueBuilder, bytes.NewBuffer(value)); err != nil { return nil, nil, err } return keyBuilder.Build(), valueBuilder.Build(), nil From 3c958349eb1374ccc331beb908f5f9aeae49be02 Mon Sep 17 00:00:00 2001 From: Will Scott Date: Wed, 23 Mar 2022 15:06:24 -0700 Subject: [PATCH 5/7] Add suport for reification --- reification.go | 189 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 reification.go diff --git a/reification.go b/reification.go new file mode 100644 index 0000000..0cca26c --- /dev/null +++ b/reification.go @@ -0,0 +1,189 @@ +package hamt + +import ( + "bytes" + "fmt" + "io" + "math/big" + + block "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + cbor "github.com/ipfs/go-ipld-cbor" + "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/codec/dagcbor" + "github.com/ipld/go-ipld-prime/linking" + cidlink "github.com/ipld/go-ipld-prime/linking/cid" + "github.com/ipld/go-ipld-prime/node/basicnode" + cbg "github.com/whyrusleeping/cbor-gen" +) + +// Reify looks at an ipld Node and tries to interpret it as a HAMT with default options. +// if successful, it returns the HAMT +func Reify(lnkCtx ipld.LinkContext, maybeHamt ipld.Node, lsys *ipld.LinkSystem) (ipld.Node, error) { + rf := MakeReifier() + return rf(lnkCtx, maybeHamt, lsys) +} + +// MakeReifier allows generation of a Reify function with an explicit hash / bitwidth. +func MakeReifier(opts ...Option) ipld.NodeReifier { + return func(lnkCtx ipld.LinkContext, maybeHamt ipld.Node, lsys *ipld.LinkSystem) (ipld.Node, error) { + if maybeHamt.Kind() != ipld.Kind_List { + return maybeHamt, nil + } + + // per Node layout: + li := maybeHamt.ListIterator() + idx, bitField, err := li.Next() + if err != nil || idx != 0 { + return maybeHamt, nil + } + bitFieldBytes, err := bitField.AsBytes() + if err != nil { + return maybeHamt, nil + } + idx, pointers, err := li.Next() + if err != nil || idx != 1 { + return maybeHamt, nil + } + if pointers.Kind() != ipld.Kind_List { + return maybeHamt, nil + } + if li.Done() != true { + return maybeHamt, nil + } + ptrs := make([]*Pointer, 0) + pti := pointers.ListIterator() + for !pti.Done() { + _, p, err := pti.Next() + if err != nil { + return maybeHamt, nil + } + ptr, err := loadPointer(p) + if err != nil { + return maybeHamt, nil + } + ptrs = append(ptrs, ptr) + } + + bs := LSBlockstore{lsys} + store := cbor.NewCborStore(&bs) + bfi := big.NewInt(0).SetBytes(bitFieldBytes) + + hn := &Node{ + Bitfield: bfi, + Pointers: ptrs, + bitWidth: defaultBitWidth, + hash: defaultHashFunction, + store: store, + proto: basicnode.Prototype.Map, + } + for _, o := range opts { + o(hn) + } + + return hn, nil + } +} + +func loadPointer(p ipld.Node) (*Pointer, error) { + if p.Kind() != ipld.Kind_Map { + return nil, fmt.Errorf("invalid pointer kind") + } + pm := p.MapIterator() + k, v, err := pm.Next() + if err != nil { + return nil, fmt.Errorf("no pointer map key") + } + ks, err := k.AsString() + if err != nil { + return nil, fmt.Errorf("pointer map key not string") + } + // this is a link. + if ks == string(keyZero) { + lnk, err := v.AsLink() + if err != nil { + return nil, fmt.Errorf("pointer union indicates link, but not link") + } + return &Pointer{Link: lnk.(cidlink.Link).Cid}, nil + // this is an array of kvs + } else if ks == string(keyOne) { + kvs := make([]*KV, 0) + li := v.ListIterator() + for !li.Done() { + _, kvn, err := li.Next() + if err != nil { + return nil, fmt.Errorf("failed to load list item: %w", err) + } + kv, err := loadKV(kvn) + if err != nil { + return nil, err + } + kvs = append(kvs, kv) + } + return &Pointer{KVs: kvs}, nil + } else { + return nil, fmt.Errorf("invalid pointer union signal") + } +} + +func loadKV(n ipld.Node) (*KV, error) { + if n.Kind() != ipld.Kind_List { + return nil, fmt.Errorf("kv should be of kind list") + } + li := n.ListIterator() + _, k, err := li.Next() + if err != nil { + return nil, err + } + kb, err := k.AsBytes() + if err != nil { + return nil, err + } + _, v, err := li.Next() + if err != nil { + return nil, err + } + if !li.Done() { + return nil, fmt.Errorf("kv did not have 2 entries as expected") + } + + buf := bytes.NewBuffer(nil) + if err := dagcbor.Encode(v, buf); err != nil { + return nil, err + } + + return &KV{ + Key: kb, + Value: &cbg.Deferred{Raw: buf.Bytes()}, + }, nil +} + +// LSBlockstore creates a blockstore (get/put) interface over a link system +type LSBlockstore struct { + *ipld.LinkSystem +} + +// Get a raw block of data from a cid using a link system storage read opener +func (l *LSBlockstore) Get(c cid.Cid) (block.Block, error) { + rdr, err := l.StorageReadOpener(linking.LinkContext{}, cidlink.Link{Cid: c}) + if err != nil { + return nil, err + } + bytes, err := io.ReadAll(rdr) + if err != nil { + return nil, err + } + return block.NewBlockWithCid(bytes, c) +} + +// Put a block of data to an underlying store using a link system storage write opener +func (l *LSBlockstore) Put(b block.Block) error { + w, committer, err := l.LinkSystem.StorageWriteOpener(linking.LinkContext{}) + if err != nil { + return err + } + if _, err := w.Write(b.RawData()); err != nil { + return err + } + return committer(cidlink.Link{Cid: b.Cid()}) +} From cce2ab8b8ea87b2121457ee0ff99d625f5a3556c Mon Sep 17 00:00:00 2001 From: Will Scott Date: Wed, 23 Mar 2022 15:33:33 -0700 Subject: [PATCH 6/7] update to current master --- hamt.go | 19 +++++++++++-------- hamt_test.go | 6 +++--- ipld.go | 45 +++++++++++++++++++++++++++------------------ options.go | 16 +++++++++++++++- reification.go | 40 ++++++++++------------------------------ 5 files changed, 66 insertions(+), 60 deletions(-) diff --git a/hamt.go b/hamt.go index c182559..6465ae5 100644 --- a/hamt.go +++ b/hamt.go @@ -179,7 +179,7 @@ func NewNode(cs cbor.IpldStore, options ...Option) (*Node, error) { } } - return newNode(cs, cfg.hashFn, cfg.bitWidth), nil + return newNode(cs, cfg.hashFn, cfg.bitWidth, cfg.proto), nil } // Find navigates through the HAMT structure to where key `k` should exist. If @@ -233,13 +233,14 @@ 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 { +func newNode(cs cbor.IpldStore, hashFn HashFunc, bitWidth int, proto ipld.NodePrototype) *Node { nd := &Node{ Bitfield: big.NewInt(0), Pointers: make([]*Pointer, 0), bitWidth: bitWidth, hash: hashFn, store: cs, + proto: proto, } return nd } @@ -274,10 +275,11 @@ func (n *Node) getValue(ctx context.Context, hv *hashBits, k string, cb func(*KV if c.isShard() { // if isShard, we have a pointer to a child that we need to load and // delegate our find operation to - chnd, err := c.loadChild(ctx, n.store, n.bitWidth, n.hash, n.proto) + chnd, err := c.loadChild(ctx, n.store, n.bitWidth, n.hash) if err != nil { return err } + chnd.proto = n.proto return chnd.getValue(ctx, hv, k, cb) } @@ -305,7 +307,6 @@ func (p *Pointer) loadChild(ctx context.Context, ns cbor.IpldStore, bitWidth int if err != nil { return nil, err } - out.proto = proto p.cache = out return out, nil @@ -445,10 +446,11 @@ func (n *Node) checkSize(ctx context.Context) (uint64, error) { totsize := uint64(len(def.Raw)) for _, ch := range n.Pointers { if ch.isShard() { - chnd, err := ch.loadChild(ctx, n.store, n.bitWidth, n.hash, n.proto) + chnd, err := ch.loadChild(ctx, n.store, n.bitWidth, n.hash) if err != nil { return 0, err } + chnd.proto = n.proto chsize, err := chnd.checkSize(ctx) if err != nil { return 0, err @@ -739,7 +741,7 @@ func (n *Node) modifyValue(ctx context.Context, hv *hashBits, k []byte, v *cbg.D if len(child.KVs) >= bucketSize { // bucket is full, create a child node (shard) with all existing bucket // elements plus the new one and set it in the place of the bucket - sub := newNode(n.store, n.hash, n.bitWidth) + sub := newNode(n.store, n.hash, n.bitWidth, n.proto) hvcopy := &hashBits{b: hv.b, consumed: hv.consumed} if _, err := sub.modifyValue(ctx, hvcopy, k, v, replace); err != nil { return UNMODIFIED, err @@ -820,7 +822,7 @@ func (n *Node) getPointer(i byte) *Pointer { // as cached nodes. 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 := newNode(n.store, n.hash, n.bitWidth, n.proto) nn.Bitfield.Set(n.Bitfield) nn.Pointers = make([]*Pointer, len(n.Pointers)) @@ -856,10 +858,11 @@ func (p *Pointer) isShard() bool { func (n *Node) ForEach(ctx context.Context, f func(k string, val *cbg.Deferred) error) error { for _, p := range n.Pointers { if p.isShard() { - chnd, err := p.loadChild(ctx, n.store, n.bitWidth, n.hash, n.proto) + chnd, err := p.loadChild(ctx, n.store, n.bitWidth, n.hash) if err != nil { return err } + chnd.proto = n.proto if err := chnd.ForEach(ctx, f); err != nil { return err diff --git a/hamt_test.go b/hamt_test.go index 5ed2666..541db07 100644 --- a/hamt_test.go +++ b/hamt_test.go @@ -428,7 +428,7 @@ func printHamt(hamt *Node) { fmt.Printf("%s‣ %v:\n", strings.Repeat(" ", depth), c) for _, p := range n.Pointers { if p.isShard() { - child, err := p.loadChild(ctx, n.store, n.bitWidth, n.hash, n.proto) + child, err := p.loadChild(ctx, n.store, n.bitWidth, n.hash) if err != nil { panic(err) } @@ -452,7 +452,7 @@ func dotGraphRec(n *Node, name *int) { if p.isShard() { *name++ fmt.Printf("\tn%d -> n%d;\n", cur, *name) - nd, err := p.loadChild(context.Background(), n.store, n.bitWidth, n.hash, n.proto) + nd, err := p.loadChild(context.Background(), n.store, n.bitWidth, n.hash) if err != nil { panic(err) } @@ -488,7 +488,7 @@ func statsrec(n *Node, st *hamtStats) { st.totalNodes++ for _, p := range n.Pointers { if p.isShard() { - nd, err := p.loadChild(context.Background(), n.store, n.bitWidth, n.hash, n.proto) + nd, err := p.loadChild(context.Background(), n.store, n.bitWidth, n.hash) if err != nil { panic(err) } diff --git a/ipld.go b/ipld.go index 7837bef..e493aac 100644 --- a/ipld.go +++ b/ipld.go @@ -6,32 +6,33 @@ import ( "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/codec/dagcbor" + "github.com/ipld/go-ipld-prime/node/basicnode" ) var _ ipld.Node = (*Node)(nil) func (n *Node) AsBool() (bool, error) { - return false, ErrNotFound + return false, ipld.ErrWrongKind{} } func (n *Node) AsBytes() ([]byte, error) { - return nil, ErrNotFound + return nil, ipld.ErrWrongKind{} } func (n *Node) AsString() (string, error) { - return "", ErrNotFound + return "", ipld.ErrWrongKind{} } func (n *Node) AsInt() (int64, error) { - return 0, ErrNotFound + return 0, ipld.ErrWrongKind{} } func (n *Node) AsFloat() (float64, error) { - return 0.0, ErrNotFound + return 0.0, ipld.ErrWrongKind{} } func (n *Node) AsLink() (ipld.Link, error) { - return nil, ErrNotFound + return nil, ipld.ErrWrongKind{} } func (n *Node) IsAbsent() bool { @@ -46,10 +47,11 @@ func (n *Node) Length() int64 { l := int64(0) for _, p := range n.Pointers { if p.Link.Defined() { - c, err := p.loadChild(context.Background(), n.store, n.bitWidth, n.hash, n.proto) + c, err := p.loadChild(context.Background(), n.store, n.bitWidth, n.hash) if err != nil { return -1 } + c.proto = n.proto l += c.Length() } else { l += int64(len(p.KVs)) @@ -71,10 +73,13 @@ func (n *Node) Kind() ipld.Kind { // // If the key does not exist, a nil node and an error will be returned. func (n *Node) LookupByString(key string) (ipld.Node, error) { - data, err := n.FindRaw(context.Background(), key) + ok, data, err := n.FindRaw(context.Background(), key) if err != nil { return nil, err } + if !ok { + return nil, ipld.ErrNotExists{} + } _, val, err := n.realize(key, data) return val, err } @@ -97,7 +102,7 @@ func (n *Node) LookupByNode(key ipld.Node) (ipld.Node, error) { } func (n *Node) LookupByIndex(idx int64) (ipld.Node, error) { - return nil, ErrNotFound + return nil, ipld.ErrWrongKind{} } func (n *Node) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { @@ -142,11 +147,12 @@ func (mi *hmi) loadNext() { p := mi.up[0] mi.up = mi.up[1:] if p.isShard() { - chld, err := p.loadChild(context.Background(), mi.at.store, mi.at.bitWidth, mi.at.hash, mi.at.proto) + chld, err := p.loadChild(context.Background(), mi.at.store, mi.at.bitWidth, mi.at.hash) if err != nil { mi.err = err return } + chld.proto = mi.at.proto mi.up = append(mi.up, chld.Pointers...) } else { mi.ukv = append(mi.ukv, p.KVs...) @@ -250,28 +256,28 @@ func (h *hamtBuilder) ValuePrototype(k string) ipld.NodePrototype { } func (h *hamtBuilder) BeginList(sizeHint int64) (ipld.ListAssembler, error) { - return nil, ErrNotFound + return nil, ipld.ErrWrongKind{} } func (h *hamtBuilder) AssignNull() error { - return ErrNotFound + return ipld.ErrWrongKind{} } func (h *hamtBuilder) AssignBool(bool) error { - return ErrNotFound + return ipld.ErrWrongKind{} } func (h *hamtBuilder) AssignInt(int64) error { - return ErrNotFound + return ipld.ErrWrongKind{} } func (h *hamtBuilder) AssignFloat(float64) error { - return ErrNotFound + return ipld.ErrWrongKind{} } func (h *hamtBuilder) AssignString(string) error { - return ErrNotFound + return ipld.ErrWrongKind{} } func (h *hamtBuilder) AssignBytes([]byte) error { - return ErrNotFound + return ipld.ErrWrongKind{} } func (h *hamtBuilder) AssignLink(ipld.Link) error { - return ErrNotFound + return ipld.ErrWrongKind{} } func (h *hamtBuilder) AssignNode(n ipld.Node) error { @@ -284,5 +290,8 @@ func (h *hamtBuilder) AssignNode(n ipld.Node) error { } func (h *hamtBuilder) Prototype() ipld.NodePrototype { + if h.proto == nil { + return basicnode.Prototype__Map{} + } return h.proto } diff --git a/options.go b/options.go index dfc09ff..8ff04db 100644 --- a/options.go +++ b/options.go @@ -1,6 +1,10 @@ package hamt -import "fmt" +import ( + "fmt" + + "github.com/ipld/go-ipld-prime" +) const bucketSize = 3 const defaultBitWidth = 8 @@ -8,6 +12,7 @@ const defaultBitWidth = 8 type config struct { bitWidth int hashFn HashFunc + proto ipld.NodePrototype } func defaultConfig() *config { @@ -58,3 +63,12 @@ func UseHashFunction(hash HashFunc) Option { return nil } } + +// WithProto creates a HAMT using a predefined prototype for values, when +// used in an IPLD ADL context. +func WithProto(p ipld.NodePrototype) Option { + return func(c *config) error { + c.proto = p + return nil + } +} diff --git a/reification.go b/reification.go index 0cca26c..754371c 100644 --- a/reification.go +++ b/reification.go @@ -13,7 +13,6 @@ import ( "github.com/ipld/go-ipld-prime/codec/dagcbor" "github.com/ipld/go-ipld-prime/linking" cidlink "github.com/ipld/go-ipld-prime/linking/cid" - "github.com/ipld/go-ipld-prime/node/basicnode" cbg "github.com/whyrusleeping/cbor-gen" ) @@ -69,46 +68,28 @@ func MakeReifier(opts ...Option) ipld.NodeReifier { store := cbor.NewCborStore(&bs) bfi := big.NewInt(0).SetBytes(bitFieldBytes) - hn := &Node{ - Bitfield: bfi, - Pointers: ptrs, - bitWidth: defaultBitWidth, - hash: defaultHashFunction, - store: store, - proto: basicnode.Prototype.Map, - } + cfg := defaultConfig() for _, o := range opts { - o(hn) + o(cfg) } + hn := newNode(store, cfg.hashFn, cfg.bitWidth, cfg.proto) + hn.Bitfield = bfi + hn.Pointers = ptrs return hn, nil } } func loadPointer(p ipld.Node) (*Pointer, error) { - if p.Kind() != ipld.Kind_Map { - return nil, fmt.Errorf("invalid pointer kind") - } - pm := p.MapIterator() - k, v, err := pm.Next() - if err != nil { - return nil, fmt.Errorf("no pointer map key") - } - ks, err := k.AsString() - if err != nil { - return nil, fmt.Errorf("pointer map key not string") - } - // this is a link. - if ks == string(keyZero) { - lnk, err := v.AsLink() + if p.Kind() != ipld.Kind_Link { + lnk, err := p.AsLink() if err != nil { return nil, fmt.Errorf("pointer union indicates link, but not link") } return &Pointer{Link: lnk.(cidlink.Link).Cid}, nil - // this is an array of kvs - } else if ks == string(keyOne) { + } else if p.Kind() == ipld.Kind_List { kvs := make([]*KV, 0) - li := v.ListIterator() + li := p.ListIterator() for !li.Done() { _, kvn, err := li.Next() if err != nil { @@ -121,9 +102,8 @@ func loadPointer(p ipld.Node) (*Pointer, error) { kvs = append(kvs, kv) } return &Pointer{KVs: kvs}, nil - } else { - return nil, fmt.Errorf("invalid pointer union signal") } + return nil, fmt.Errorf("unsupported pointer kind") } func loadKV(n ipld.Node) (*KV, error) { From cc709b83f49e4b93b52d1a687aabe1bac80f2c38 Mon Sep 17 00:00:00 2001 From: Will Scott Date: Wed, 23 Mar 2022 15:35:37 -0700 Subject: [PATCH 7/7] static --- reification.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reification.go b/reification.go index 754371c..ef97f72 100644 --- a/reification.go +++ b/reification.go @@ -47,7 +47,7 @@ func MakeReifier(opts ...Option) ipld.NodeReifier { if pointers.Kind() != ipld.Kind_List { return maybeHamt, nil } - if li.Done() != true { + if !li.Done() { return maybeHamt, nil } ptrs := make([]*Pointer, 0)