84 lines
2.0 KiB
Go
84 lines
2.0 KiB
Go
|
package retrievaladapter
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"path/filepath"
|
||
|
"sync"
|
||
|
|
||
|
"github.com/ipfs/go-cid"
|
||
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||
|
"github.com/ipld/go-car/v2/blockstore"
|
||
|
|
||
|
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||
|
)
|
||
|
|
||
|
// ProxyBlockstoreAccessor is an accessor that returns a fixed blockstore.
|
||
|
// To be used in combination with IPFS integration.
|
||
|
type ProxyBlockstoreAccessor struct {
|
||
|
Blockstore bstore.Blockstore
|
||
|
}
|
||
|
|
||
|
var _ retrievalmarket.BlockstoreAccessor = (*ProxyBlockstoreAccessor)(nil)
|
||
|
|
||
|
func NewFixedBlockstoreAccessor(bs bstore.Blockstore) retrievalmarket.BlockstoreAccessor {
|
||
|
return &ProxyBlockstoreAccessor{Blockstore: bs}
|
||
|
}
|
||
|
|
||
|
func (p *ProxyBlockstoreAccessor) Get(_ retrievalmarket.DealID, _ retrievalmarket.PayloadCID) (bstore.Blockstore, error) {
|
||
|
return p.Blockstore, nil
|
||
|
}
|
||
|
|
||
|
func (p *ProxyBlockstoreAccessor) Done(_ retrievalmarket.DealID) error {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
type CARBlockstoreAccessor struct {
|
||
|
rootdir string
|
||
|
lk sync.Mutex
|
||
|
open map[retrievalmarket.DealID]*blockstore.ReadWrite
|
||
|
}
|
||
|
|
||
|
var _ retrievalmarket.BlockstoreAccessor = (*CARBlockstoreAccessor)(nil)
|
||
|
|
||
|
func NewCARBlockstoreAccessor(rootdir string) *CARBlockstoreAccessor {
|
||
|
return &CARBlockstoreAccessor{
|
||
|
rootdir: rootdir,
|
||
|
open: make(map[retrievalmarket.DealID]*blockstore.ReadWrite),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (c *CARBlockstoreAccessor) Get(id retrievalmarket.DealID, payloadCid retrievalmarket.PayloadCID) (bstore.Blockstore, error) {
|
||
|
c.lk.Lock()
|
||
|
defer c.lk.Unlock()
|
||
|
|
||
|
bs, ok := c.open[id]
|
||
|
if ok {
|
||
|
return bs, nil
|
||
|
}
|
||
|
|
||
|
path := c.PathFor(id)
|
||
|
bs, err := blockstore.OpenReadWrite(path, []cid.Cid{payloadCid}, blockstore.UseWholeCIDs(true))
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
c.open[id] = bs
|
||
|
return bs, nil
|
||
|
}
|
||
|
|
||
|
func (c *CARBlockstoreAccessor) Done(id retrievalmarket.DealID) error {
|
||
|
c.lk.Lock()
|
||
|
defer c.lk.Unlock()
|
||
|
|
||
|
bs, ok := c.open[id]
|
||
|
if !ok {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
delete(c.open, id)
|
||
|
return bs.Finalize()
|
||
|
}
|
||
|
|
||
|
func (c *CARBlockstoreAccessor) PathFor(id retrievalmarket.DealID) string {
|
||
|
return filepath.Join(c.rootdir, fmt.Sprintf("%d.car", id))
|
||
|
}
|