Skip to content

Commit

Permalink
feat: remove block decoding global registry
Browse files Browse the repository at this point in the history
  • Loading branch information
aschmahmann committed May 30, 2023
1 parent e379dec commit c3da01c
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 53 deletions.
50 changes: 3 additions & 47 deletions coding.go
Original file line number Diff line number Diff line change
@@ -1,62 +1,18 @@
package format

import (
"fmt"
"sync"

blocks "github.com/ipfs/go-block-format"
)

// DecodeBlockFunc functions decode blocks into nodes.
type DecodeBlockFunc func(block blocks.Block) (Node, error)

type BlockDecoder interface {
Register(codec uint64, decoder DecodeBlockFunc)
Decode(blocks.Block) (Node, error)
}
type safeBlockDecoder struct {
// Can be replaced with an RCU if necessary.
lock sync.RWMutex
decoders map[uint64]DecodeBlockFunc
}

// Register registers decoder for all blocks with the passed codec.
//
// This will silently replace any existing registered block decoders.
func (d *safeBlockDecoder) Register(codec uint64, decoder DecodeBlockFunc) {
d.lock.Lock()
defer d.lock.Unlock()
d.decoders[codec] = decoder
}

func (d *safeBlockDecoder) Decode(block blocks.Block) (Node, error) {
// Decode decodes the given block using passed DecodeBlockFunc.
func Decode(block blocks.Block, decoder DecodeBlockFunc) (Node, error) {
// Short-circuit by cast if we already have a Node.
if node, ok := block.(Node); ok {
return node, nil
}

ty := block.Cid().Type()

d.lock.RLock()
decoder, ok := d.decoders[ty]
d.lock.RUnlock()

if ok {
return decoder(block)
} else {
// TODO: get the *long* name for this format
return nil, fmt.Errorf("unrecognized object type: %d", ty)
}
}

var DefaultBlockDecoder BlockDecoder = &safeBlockDecoder{decoders: make(map[uint64]DecodeBlockFunc)}

// Decode decodes the given block using the default BlockDecoder.
func Decode(block blocks.Block) (Node, error) {
return DefaultBlockDecoder.Decode(block)
}

// Register registers block decoders with the default BlockDecoder.
func Register(codec uint64, decoder DecodeBlockFunc) {
DefaultBlockDecoder.Register(codec, decoder)
return decoder(block)
}
10 changes: 4 additions & 6 deletions coding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@ import (
mh "github.com/multiformats/go-multihash"
)

func init() {
Register(cid.Raw, func(b blocks.Block) (Node, error) {
func TestDecode(t *testing.T) {
decoder := func(b blocks.Block) (Node, error) {
node := &EmptyNode{}
if b.RawData() != nil || !b.Cid().Equals(node.Cid()) {
return nil, errors.New("can only decode empty blocks")
}
return node, nil
})
}
}

func TestDecode(t *testing.T) {
id, err := cid.Prefix{
Version: 1,
Codec: cid.Raw,
Expand All @@ -35,7 +33,7 @@ func TestDecode(t *testing.T) {
if err != nil {
t.Fatalf("failed to create empty block: %s", err)
}
node, err := Decode(block)
node, err := Decode(block, decoder)
if err != nil {
t.Fatalf("failed to decode empty node: %s", err)
}
Expand Down

0 comments on commit c3da01c

Please sign in to comment.