3795cc2bd2
This paves the way for better object lifetime management. Concretely, it makes it possible to: - have different stores backing chain and state data. - having the same datastore library, but using different parameters. - attach different caching layers/policies to each class of data, e.g. sizing caches differently. - specifying different retention policies for chain and state data. This separation is important because: - access patterns/frequency of chain and state data are different. - state is derivable from chain, so one could never expunge the chain store, and only retain state objects reachable from the last finality in the state store.
111 lines
3.2 KiB
Go
111 lines
3.2 KiB
Go
package retrievalstoremgr
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"github.com/filecoin-project/go-multistore"
|
|
"github.com/filecoin-project/lotus/blockstore"
|
|
"github.com/filecoin-project/lotus/node/repo/importmgr"
|
|
"github.com/ipfs/go-blockservice"
|
|
offline "github.com/ipfs/go-ipfs-exchange-offline"
|
|
ipldformat "github.com/ipfs/go-ipld-format"
|
|
"github.com/ipfs/go-merkledag"
|
|
)
|
|
|
|
// RetrievalStore references a store for a retrieval deal
|
|
// which may or may not have a multistore ID associated with it
|
|
type RetrievalStore interface {
|
|
StoreID() *multistore.StoreID
|
|
DAGService() ipldformat.DAGService
|
|
}
|
|
|
|
// RetrievalStoreManager manages stores for retrieval deals, abstracting
|
|
// the underlying storage mechanism
|
|
type RetrievalStoreManager interface {
|
|
NewStore() (RetrievalStore, error)
|
|
ReleaseStore(RetrievalStore) error
|
|
}
|
|
|
|
// MultiStoreRetrievalStoreManager manages stores on top of the import manager
|
|
type MultiStoreRetrievalStoreManager struct {
|
|
imgr *importmgr.Mgr
|
|
}
|
|
|
|
var _ RetrievalStoreManager = &MultiStoreRetrievalStoreManager{}
|
|
|
|
// NewMultiStoreRetrievalStoreManager returns a new multstore based RetrievalStoreManager
|
|
func NewMultiStoreRetrievalStoreManager(imgr *importmgr.Mgr) RetrievalStoreManager {
|
|
return &MultiStoreRetrievalStoreManager{
|
|
imgr: imgr,
|
|
}
|
|
}
|
|
|
|
// NewStore creates a new store (uses multistore)
|
|
func (mrsm *MultiStoreRetrievalStoreManager) NewStore() (RetrievalStore, error) {
|
|
storeID, store, err := mrsm.imgr.NewStore()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &multiStoreRetrievalStore{storeID, store}, nil
|
|
}
|
|
|
|
// ReleaseStore releases a store (uses multistore remove)
|
|
func (mrsm *MultiStoreRetrievalStoreManager) ReleaseStore(retrievalStore RetrievalStore) error {
|
|
mrs, ok := retrievalStore.(*multiStoreRetrievalStore)
|
|
if !ok {
|
|
return errors.New("Cannot release this store type")
|
|
}
|
|
return mrsm.imgr.Remove(mrs.storeID)
|
|
}
|
|
|
|
type multiStoreRetrievalStore struct {
|
|
storeID multistore.StoreID
|
|
store *multistore.Store
|
|
}
|
|
|
|
func (mrs *multiStoreRetrievalStore) StoreID() *multistore.StoreID {
|
|
return &mrs.storeID
|
|
}
|
|
|
|
func (mrs *multiStoreRetrievalStore) DAGService() ipldformat.DAGService {
|
|
return mrs.store.DAG
|
|
}
|
|
|
|
// BlockstoreRetrievalStoreManager manages a single blockstore as if it were multiple stores
|
|
type BlockstoreRetrievalStoreManager struct {
|
|
bs blockstore.BasicBlockstore
|
|
}
|
|
|
|
var _ RetrievalStoreManager = &BlockstoreRetrievalStoreManager{}
|
|
|
|
// NewBlockstoreRetrievalStoreManager returns a new blockstore based RetrievalStoreManager
|
|
func NewBlockstoreRetrievalStoreManager(bs blockstore.BasicBlockstore) RetrievalStoreManager {
|
|
return &BlockstoreRetrievalStoreManager{
|
|
bs: bs,
|
|
}
|
|
}
|
|
|
|
// NewStore creates a new store (just uses underlying blockstore)
|
|
func (brsm *BlockstoreRetrievalStoreManager) NewStore() (RetrievalStore, error) {
|
|
return &blockstoreRetrievalStore{
|
|
dagService: merkledag.NewDAGService(blockservice.New(brsm.bs, offline.Exchange(brsm.bs))),
|
|
}, nil
|
|
}
|
|
|
|
// ReleaseStore for this implementation does nothing
|
|
func (brsm *BlockstoreRetrievalStoreManager) ReleaseStore(RetrievalStore) error {
|
|
return nil
|
|
}
|
|
|
|
type blockstoreRetrievalStore struct {
|
|
dagService ipldformat.DAGService
|
|
}
|
|
|
|
func (brs *blockstoreRetrievalStore) StoreID() *multistore.StoreID {
|
|
return nil
|
|
}
|
|
|
|
func (brs *blockstoreRetrievalStore) DAGService() ipldformat.DAGService {
|
|
return brs.dagService
|
|
}
|