From e82c5339287f4625b8153033efb14f54acea9aa2 Mon Sep 17 00:00:00 2001 From: gammazero <11790789+gammazero@users.noreply.github.com> Date: Tue, 6 Aug 2024 10:41:09 -0700 Subject: [PATCH 1/2] change Block to a value struct The goal is to stop doing two allocations for each block (now it will only allocate the []byte buffer, and pass the cid.Cid, []byte pair by decomposed registers or stack). This way of changing does not change the syntax for trivial uses of block.Block, so in theory we will have to update only producers of block.Block, not consumers. Fixes #45 Replaces https://github.com/ipfs/boxo/pull/192 Note: This change will cause a failure here: https://github.com/ipfs/go-ipld-format/blob/0f7aff00f72e9dea0d9718bc0972e309ba7c3e8d/format.go#L27 --- blocks.go | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/blocks.go b/blocks.go index 770c9a3..c0c63b7 100644 --- a/blocks.go +++ b/blocks.go @@ -16,66 +16,57 @@ import ( // according to the contents. It is currently used only when debugging. var ErrWrongHash = errors.New("data did not match given hash") -// Block provides abstraction for blocks implementations. -type Block interface { - RawData() []byte - Cid() cid.Cid - String() string - Loggable() map[string]interface{} -} - -// A BasicBlock is a singular block of data in ipfs. It implements the Block -// interface. -type BasicBlock struct { +// A Block is a singular block of data in ipfs. This is some bytes addressed by a hash. +type Block struct { cid cid.Cid data []byte } // NewBlock creates a Block object from opaque data. It will hash the data. -func NewBlock(data []byte) *BasicBlock { +func NewBlock(data []byte) Block { // TODO: fix assumptions - return &BasicBlock{data: data, cid: cid.NewCidV0(u.Hash(data))} + return Block{data: data, cid: cid.NewCidV0(u.Hash(data))} } // NewBlockWithCid creates a new block when the hash of the data // is already known, this is used to save time in situations where // we are able to be confident that the data is correct. -func NewBlockWithCid(data []byte, c cid.Cid) (*BasicBlock, error) { +func NewBlockWithCid(data []byte, c cid.Cid) (Block, error) { if u.Debug { chkc, err := c.Prefix().Sum(data) if err != nil { - return nil, err + return Block{}, err } if !chkc.Equals(c) { - return nil, ErrWrongHash + return Block{}, ErrWrongHash } } - return &BasicBlock{data: data, cid: c}, nil + return Block{data: data, cid: c}, nil } // Multihash returns the hash contained in the block CID. -func (b *BasicBlock) Multihash() mh.Multihash { +func (b Block) Multihash() mh.Multihash { return b.cid.Hash() } // RawData returns the block raw contents as a byte slice. -func (b *BasicBlock) RawData() []byte { +func (b Block) RawData() []byte { return b.data } // Cid returns the content identifier of the block. -func (b *BasicBlock) Cid() cid.Cid { +func (b Block) Cid() cid.Cid { return b.cid } // String provides a human-readable representation of the block CID. -func (b *BasicBlock) String() string { +func (b Block) String() string { return fmt.Sprintf("[Block %s]", b.Cid()) } // Loggable returns a go-log loggable item. -func (b *BasicBlock) Loggable() map[string]interface{} { +func (b Block) Loggable() map[string]interface{} { return map[string]interface{}{ "block": b.Cid().String(), } From 0bd1b92f3aaa875a90705c85afdc1eb32218dfe0 Mon Sep 17 00:00:00 2001 From: gammazero <11790789+gammazero@users.noreply.github.com> Date: Mon, 9 Jun 2025 05:02:38 -1000 Subject: [PATCH 2/2] Add block interface for interoperability --- blocks.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/blocks.go b/blocks.go index c0c63b7..6b26194 100644 --- a/blocks.go +++ b/blocks.go @@ -16,12 +16,22 @@ import ( // according to the contents. It is currently used only when debugging. var ErrWrongHash = errors.New("data did not match given hash") +// Interface provides abstraction for blocks implementations. +type Interface interface { + RawData() []byte + Cid() cid.Cid + String() string + Loggable() map[string]interface{} +} + // A Block is a singular block of data in ipfs. This is some bytes addressed by a hash. type Block struct { cid cid.Cid data []byte } +var _ Interface = Block{} + // NewBlock creates a Block object from opaque data. It will hash the data. func NewBlock(data []byte) Block { // TODO: fix assumptions