From 2f663fff1e9b698cb42b88c8c95980a05f29138a Mon Sep 17 00:00:00 2001 From: Jorropo Date: Mon, 12 Jun 2023 11:15:29 +0200 Subject: [PATCH] unixfs: Add support for byte slices backed CIDs for zero allocations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` $ benchstat /mnt/ramdisk/{old,new} name old time/op new time/op delta PB-12 730ns ± 5% 255ns ± 2% -65.04% (p=0.000 n=9+10) name old alloc/op new alloc/op delta PB-12 224B ± 0% 0B -100.00% (p=0.000 n=10+10) name old allocs/op new allocs/op delta PB-12 4.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10) ``` Depends on https://github.com/ipfs/go-cid/pull/159. --- examples/go.mod | 6 ++--- examples/go.sum | 12 ++++----- go.mod | 6 ++--- go.sum | 12 ++++----- unixfs/pb.go | 28 ++++++++++--------- unixfs/pb_test.go | 7 ++--- unixfs/unixfs.go | 62 +++++++++++++++++++++++-------------------- unixfs/unixfs_test.go | 21 ++++++++------- 8 files changed, 82 insertions(+), 72 deletions(-) diff --git a/examples/go.mod b/examples/go.mod index 0d9ddad09..f84a1d9e6 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -6,7 +6,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/ipfs/boxo v0.7.1-0.20230323075409-f4a8dd6614df github.com/ipfs/go-block-format v0.1.2 - github.com/ipfs/go-cid v0.4.0 + github.com/ipfs/go-cid v0.4.2-0.20230612091241-80d1e915f662 github.com/ipfs/go-datastore v0.6.0 github.com/ipld/go-ipld-prime v0.20.0 github.com/libp2p/go-libp2p v0.26.3 @@ -102,8 +102,8 @@ require ( github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect - github.com/multiformats/go-multibase v0.1.1 // indirect - github.com/multiformats/go-multihash v0.2.1 // indirect + github.com/multiformats/go-multibase v0.2.0 // indirect + github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.5.1 // indirect diff --git a/examples/go.sum b/examples/go.sum index 8e6652fff..f95d4a076 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -284,8 +284,8 @@ github.com/ipfs/go-blockservice v0.5.0 h1:B2mwhhhVQl2ntW2EIpaWPwSCxSuqr5fFA93Ms4 github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.4.0 h1:a4pdZq0sx6ZSxbCizebnKiMCx/xI/aBBFlB73IgH4rA= -github.com/ipfs/go-cid v0.4.0/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= +github.com/ipfs/go-cid v0.4.2-0.20230612091241-80d1e915f662 h1:jWQ5yOEmR1Fvv6Rj8mEye4QTeGQoKKECMieju9z5kgA= +github.com/ipfs/go-cid v0.4.2-0.20230612091241-80d1e915f662/go.mod h1:4rtyA9XdBeZBapaRNJuTY9H+/6bG4URx/cVwjAzK6fw= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= @@ -469,16 +469,16 @@ github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/e github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= -github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= -github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= -github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= +github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= +github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= diff --git a/go.mod b/go.mod index 5a9c3ce70..4ce6a978f 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/ipfs/bbloom v0.0.4 github.com/ipfs/go-bitfield v1.1.0 github.com/ipfs/go-block-format v0.1.2 - github.com/ipfs/go-cid v0.4.0 + github.com/ipfs/go-cid v0.4.2-0.20230612091241-80d1e915f662 github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-detect-race v0.0.1 @@ -48,9 +48,9 @@ require ( github.com/multiformats/go-base32 v0.1.0 github.com/multiformats/go-multiaddr v0.8.0 github.com/multiformats/go-multiaddr-dns v0.3.1 - github.com/multiformats/go-multibase v0.1.1 + github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.8.1 - github.com/multiformats/go-multihash v0.2.1 + github.com/multiformats/go-multihash v0.2.3 github.com/multiformats/go-multistream v0.4.1 github.com/multiformats/go-varint v0.0.7 github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 diff --git a/go.sum b/go.sum index 19a2a5793..4d08f8af7 100644 --- a/go.sum +++ b/go.sum @@ -289,8 +289,8 @@ github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUP github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.4.0 h1:a4pdZq0sx6ZSxbCizebnKiMCx/xI/aBBFlB73IgH4rA= -github.com/ipfs/go-cid v0.4.0/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= +github.com/ipfs/go-cid v0.4.2-0.20230612091241-80d1e915f662 h1:jWQ5yOEmR1Fvv6Rj8mEye4QTeGQoKKECMieju9z5kgA= +github.com/ipfs/go-cid v0.4.2-0.20230612091241-80d1e915f662/go.mod h1:4rtyA9XdBeZBapaRNJuTY9H+/6bG4URx/cVwjAzK6fw= github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= @@ -492,16 +492,16 @@ github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/e github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= -github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= -github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= -github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= +github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= +github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= diff --git a/unixfs/pb.go b/unixfs/pb.go index 2aba7a0a1..13aa72365 100644 --- a/unixfs/pb.go +++ b/unixfs/pb.go @@ -69,7 +69,11 @@ const ( // optional Data Data = 1; // } -func parsePB(fileChildrens []FileEntry, directoryChildrens []DirectoryEntry, inCid cid.Cid, origData []byte) (typ Type, file File, dir Directory, sym Symlink, err error) { +func parsePB[Self, Children cid.Storage]( + fileChildrens []FileEntry[Children], + directoryChildrens []DirectoryEntry[Children], + inCid cid.GenericCid[Self], origData []byte, +) (typ Type, file File[Self, Children], dir Directory[Self, Children], sym Symlink[Self], err error) { var dataType uint64 var fileLinks, blocksizes uint var content []byte @@ -81,8 +85,8 @@ func parsePB(fileChildrens []FileEntry, directoryChildrens []DirectoryEntry, inC // FIXME: is an empty name a valid file name in a directory ? directoryChildrens = slices.Grow(directoryChildrens, len(fileChildrens)+extra) for _, v := range fileChildrens { - directoryChildrens = append(directoryChildrens, DirectoryEntry{ - Entry: Entry{Cid: v.Cid, tSize: v.tSize}, + directoryChildrens = append(directoryChildrens, DirectoryEntry[Children]{ + Entry: Entry[Children]{Cid: v.Cid, tSize: v.tSize}, Name: AliasableString{}, }) } @@ -126,7 +130,7 @@ func parsePB(fileChildrens []FileEntry, directoryChildrens []DirectoryEntry, inC } // FIXME: add support aliased CIDs in github.com/ipfs/go-cid - var c cid.Cid + var c cid.GenericCid[Children] var name []byte var tSize uint64 // will be offset by +1, zero means not found @@ -182,7 +186,7 @@ func parsePB(fileChildrens []FileEntry, directoryChildrens []DirectoryEntry, inC fileChildrens[blocksizes].FileSize = blocksize } else { // we have discovered more blocksizes than links at this point, add new entries - fileChildrens = append(fileChildrens, FileEntry{FileSize: blocksize}) + fileChildrens = append(fileChildrens, FileEntry[Children]{FileSize: blocksize}) } blocksizes++ return nil @@ -244,7 +248,7 @@ func parsePB(fileChildrens []FileEntry, directoryChildrens []DirectoryEntry, inC } mData = mData[l:] - c, err = cid.Cast(cBytes) + c, err = cid.CastGeneric[Children](cBytes) if err != nil { err = fmt.Errorf("failed to decode cid: %w", err) return @@ -293,7 +297,7 @@ func parsePB(fileChildrens []FileEntry, directoryChildrens []DirectoryEntry, inC if outerNumber == 2 { // repeated PBLink Links = 2; - if c == cid.Undef { + if !c.Defined() { err = errors.New("link is missing CID") } @@ -310,8 +314,8 @@ func parsePB(fileChildrens []FileEntry, directoryChildrens []DirectoryEntry, inC moveZeroNamedDirectoryEntriesToDirectoryChildrens(1) } - directoryChildrens = append(directoryChildrens, DirectoryEntry{ - Entry: Entry{Cid: c, tSize: tSize}, + directoryChildrens = append(directoryChildrens, DirectoryEntry[Children]{ + Entry: Entry[Children]{Cid: c, tSize: tSize}, Name: AliasableString(name), }) } else { @@ -322,7 +326,7 @@ func parsePB(fileChildrens []FileEntry, directoryChildrens []DirectoryEntry, inC fileChildrens[fileLinks].tSize = tSize } else { // we have discovered more links than blocksizes at this point, add new entries - fileChildrens = append(fileChildrens, FileEntry{Entry: Entry{Cid: c, tSize: tSize}}) + fileChildrens = append(fileChildrens, FileEntry[Children]{Entry: Entry[Children]{Cid: c, tSize: tSize}}) } fileLinks++ } @@ -354,8 +358,8 @@ func parsePB(fileChildrens []FileEntry, directoryChildrens []DirectoryEntry, inC } typ = TFile - file = File{ - Entry: Entry{Cid: inCid, tSize: selfTSize + uint64(len(origData))}, + file = File[Self, Children]{ + Entry: Entry[Self]{Cid: inCid, tSize: selfTSize + uint64(len(origData))}, Data: content, Childrens: fileChildrens, } diff --git a/unixfs/pb_test.go b/unixfs/pb_test.go index cda4a8792..b83d22f0c 100644 --- a/unixfs/pb_test.go +++ b/unixfs/pb_test.go @@ -19,10 +19,10 @@ func BenchmarkPB(b *testing.B) { if err != nil { b.Fatal() } - c := cid.NewCidV0(mh) + c := cid.NewCidV0Generic[[]byte](mh) b.ResetTimer() - var out []FileEntry + var out []FileEntry[[]byte] for i := b.N; i != 0; i-- { _, f, _, _, _ := parsePB(out[:0], nil, c, data) out = f.Childrens @@ -40,6 +40,7 @@ func FuzzPB(f *testing.F) { // Assume a block limit is inplace. return } - parsePB(nil, nil, cid.Undef, b) + var zero cid.GenericCid[[]byte] + parsePB[[]byte, []byte](nil, nil, zero, b) }) } diff --git a/unixfs/unixfs.go b/unixfs/unixfs.go index a5b3584c7..e8b926cb6 100644 --- a/unixfs/unixfs.go +++ b/unixfs/unixfs.go @@ -17,14 +17,14 @@ import ( ) // Entry is a basic unit block. -type Entry struct { - Cid cid.Cid +type Entry[S cid.Storage] struct { + Cid cid.GenericCid[S] // tSize encode the comulative size of the DAG. // the zero value indicates tsize is missing. tSize uint64 } -func (e Entry) TSize() (tsize uint64, ok bool) { +func (e Entry[S]) TSize() (tsize uint64, ok bool) { if e.tSize == 0 { return 0, false } @@ -32,47 +32,47 @@ func (e Entry) TSize() (tsize uint64, ok bool) { return e.tSize - 1, true } -func (e Entry) Untyped() Entry { +func (e Entry[S]) Untyped() Entry[S] { return e } -var _ Node = File{} +var _ Node[string] = File[string, string]{} -type File struct { +type File[Self, Children cid.Storage] struct { badge - Entry + Entry[Self] Data []byte - Childrens []FileEntry + Childrens []FileEntry[Children] } -func FileEntryWithTSize(c cid.Cid, fileSize, tSize uint64) FileEntry { - return FileEntry{Entry: Entry{Cid: c, tSize: tSize + 1}, FileSize: fileSize} +func FileEntryWithTSize[S cid.Storage](c cid.GenericCid[S], fileSize, tSize uint64) FileEntry[S] { + return FileEntry[S]{Entry: Entry[S]{Cid: c, tSize: tSize + 1}, FileSize: fileSize} } -type FileEntry struct { - Entry +type FileEntry[S cid.Storage] struct { + Entry[S] // FileSize is the logical size of the file at this location once decoded. FileSize uint64 } -var _ Node = Directory{} +var _ Node[string] = Directory[string, string]{} -type Directory struct { +type Directory[Self, Children cid.Storage] struct { badge - Entry - Childrens []DirectoryEntry + Entry[Self] + Childrens []DirectoryEntry[Children] } -type DirectoryEntry struct { - Entry +type DirectoryEntry[S cid.Storage] struct { + Entry[S] Name AliasableString } -var _ Node = Symlink{} +var _ Node[string] = Symlink[string]{} -type Symlink struct { +type Symlink[S cid.Storage] struct { badge - Entry + Entry[S] Value []byte } @@ -86,9 +86,9 @@ func (badge) nodeBadge() { // Node is an interface that can exclusively be a [File], [Directory] or [Symlink]. We might add more in the future. // You MUST NOT embed this interface, it's only purpose is to provide type safe enums. -type Node interface { +type Node[S cid.Storage] interface { // Untyped returns the untyped [Entry] for that value stripped of all type related information. - Untyped() Entry + Untyped() Entry[S] // nodeBadge must never be called it's just here to trick the type checker. nodeBadge() } @@ -97,8 +97,8 @@ type Node interface { // [File.Data], [DirectoryEntry.Name] and [Symlink.Value] values are aliased to b.RawData(). // The data argument MUST hash to cid, this wont check the validaty of the hash. // It assumes the size of the block is limited and reasonable. -func Parse(b blocks.Block) (Node, error) { - switch t, f, d, s, err := ParseAppend(nil, nil, b.Cid(), b.RawData()); t { +func Parse[Children cid.Storage](b blocks.Block) (Node[string], error) { + switch t, f, d, s, err := ParseAppend[string, Children](nil, nil, b.Cid(), b.RawData()); t { case TError: return nil, err case TFile: @@ -121,7 +121,11 @@ func Parse(b blocks.Block) (Node, error) { // It only ever clobber extra capacity within the slices, it may do so in the case of an error. // The data argument MUST hash to cid, this wont check the validaty of the hash. // It assumes the size of the block is limited and reasonable. -func ParseAppend(fileChildrens []FileEntry, directoryChildrens []DirectoryEntry, inCid cid.Cid, data []byte) (t Type, f File, d Directory, s Symlink, err error) { +func ParseAppend[Self, Children cid.Storage]( + fileChildrens []FileEntry[Children], + directoryChildrens []DirectoryEntry[Children], + inCid cid.GenericCid[Self], data []byte, +) (t Type, f File[Self, Children], d Directory[Self, Children], s Symlink[Self], err error) { // Avoid clobbering the used part of the slice. fileChildrens = fileChildrens[len(fileChildrens):] directoryChildrens = directoryChildrens[len(directoryChildrens):] @@ -130,8 +134,8 @@ func ParseAppend(fileChildrens []FileEntry, directoryChildrens []DirectoryEntry, switch c := multicodec.Code(pref.Codec); c { case multicodec.Raw: t = TFile - f = File{ - Entry: Entry{ + f = File[Self, Children]{ + Entry: Entry[Self]{ Cid: inCid, tSize: uint64(len(data)) + 1, }, @@ -140,7 +144,7 @@ func ParseAppend(fileChildrens []FileEntry, directoryChildrens []DirectoryEntry, } return case multicodec.DagPb: - return parsePB(fileChildrens, directoryChildrens, inCid, data) + return parsePB[Self, Children](fileChildrens, directoryChildrens, inCid, data) default: err = errors.New("unsupported codec: " + c.String()) return diff --git a/unixfs/unixfs_test.go b/unixfs/unixfs_test.go index 3158ed13b..09320f480 100644 --- a/unixfs/unixfs_test.go +++ b/unixfs/unixfs_test.go @@ -9,6 +9,7 @@ import ( blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" mh "github.com/multiformats/go-multihash" + "golang.org/x/exp/slices" ) func TestRaw(t *testing.T) { @@ -20,7 +21,7 @@ func TestRaw(t *testing.T) { } c := cid.NewCidV1(cid.Raw, mh) - validate := func(t *testing.T, f File) { + validate := func(t *testing.T, f File[string, string]) { if !bytes.Equal(data, f.Data) { t.Errorf("expected %v got %v", data, f.Data) } @@ -44,11 +45,11 @@ func TestRaw(t *testing.T) { if err != nil { t.Fatal(err) } - a, err := Parse(b) + a, err := Parse[string](b) if err != nil { t.Fatal(err) } - f, ok := a.(File) + f, ok := a.(File[string, string]) if !ok { t.Fatalf("expected File got %T", a) } @@ -56,7 +57,7 @@ func TestRaw(t *testing.T) { }) t.Run("ParseAppend", func(t *testing.T) { t.Parallel() - var someArr [2]FileEntry + var someArr [2]FileEntry[string] typ, f, _, _, err := ParseAppend(someArr[:1], nil, c, data) if err != nil { t.Fatal(err) @@ -86,12 +87,12 @@ func TestFilePB(t *testing.T) { const firstChildrenTSize = 45623854 const secondChildrenTSize = 1690667 - expectedChildrens := [2]FileEntry{ + expectedChildrens := [2]FileEntry[string]{ FileEntryWithTSize(cid.MustParse("QmUBwP7RczPWbJSCpR4BygzvTNbJ2sfjt5yuRphSVYaJar"), 45613056, firstChildrenTSize), FileEntryWithTSize(cid.MustParse("QmeKhUSkRVDFbxssXpnb15UQf25YdWN9Ck3rjfZA3tvD8h"), 1690225, secondChildrenTSize), } - validate := func(t *testing.T, f File) { + validate := func(t *testing.T, f File[string, string]) { if f.Cid != c { t.Errorf("expected %v cid got %v", c, f.Cid) } @@ -109,7 +110,7 @@ func TestFilePB(t *testing.T) { if len(f.Childrens) != 2 { t.Errorf("expected 2 childrens got %v", f.Childrens) - } else if *(*[2]FileEntry)(f.Childrens) != expectedChildrens { + } else if !slices.Equal(f.Childrens, expectedChildrens[:]) { t.Errorf("childrens don't match, expected %v got %v", expectedChildrens, f.Childrens) } } @@ -120,11 +121,11 @@ func TestFilePB(t *testing.T) { if err != nil { t.Fatal(err) } - a, err := Parse(b) + a, err := Parse[string](b) if err != nil { t.Fatal(err) } - f, ok := a.(File) + f, ok := a.(File[string, string]) if !ok { t.Fatalf("expected File got %T", a) } @@ -132,7 +133,7 @@ func TestFilePB(t *testing.T) { }) t.Run("ParseAppend", func(t *testing.T) { t.Parallel() - var someArr [3]FileEntry + var someArr [3]FileEntry[string] typ, f, _, _, err := ParseAppend(someArr[:1], nil, c, data) if err != nil { t.Fatal(err)