github.com/ipld/go-ipld-prime@v0.21.0/linking/cid/memorystorage.go (about)

     1  package cidlink
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  
     9  	"github.com/ipld/go-ipld-prime/datamodel"
    10  	"github.com/ipld/go-ipld-prime/linking"
    11  )
    12  
    13  // Memory is a simple in-memory storage for cidlinks. It's the same as `storage.Memory`
    14  // but uses typical multihash semantics used when reading/writing cidlinks.
    15  //
    16  // Using multihash as the storage key rather than the whole CID will remove the
    17  // distinction between CIDv0 and their CIDv1 counterpart. It also removes the
    18  // distinction between CIDs where the multihash is the same but the codec is
    19  // different, e.g. `dag-cbor` and a `raw` version of the same data.
    20  type Memory struct {
    21  	Bag map[string][]byte
    22  }
    23  
    24  func (store *Memory) beInitialized() {
    25  	if store.Bag != nil {
    26  		return
    27  	}
    28  	store.Bag = make(map[string][]byte)
    29  }
    30  
    31  func (store *Memory) OpenRead(lnkCtx linking.LinkContext, lnk datamodel.Link) (io.Reader, error) {
    32  	store.beInitialized()
    33  	cl, ok := lnk.(Link)
    34  	if !ok {
    35  		return nil, fmt.Errorf("incompatible link type: %T", lnk)
    36  	}
    37  	data, exists := store.Bag[string(cl.Hash())]
    38  	if !exists {
    39  		return nil, os.ErrNotExist
    40  	}
    41  	return bytes.NewReader(data), nil
    42  }
    43  
    44  func (store *Memory) OpenWrite(lnkCtx linking.LinkContext) (io.Writer, linking.BlockWriteCommitter, error) {
    45  	store.beInitialized()
    46  	buf := bytes.Buffer{}
    47  	return &buf, func(lnk datamodel.Link) error {
    48  		cl, ok := lnk.(Link)
    49  		if !ok {
    50  			return fmt.Errorf("incompatible link type: %T", lnk)
    51  		}
    52  
    53  		store.Bag[string(cl.Hash())] = buf.Bytes()
    54  		return nil
    55  	}, nil
    56  }