From 46f4ce2773d39b6e97569978b2f86072da7706ba Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 22 Apr 2022 16:29:43 +0300 Subject: [PATCH] [#1324] engine: Implement Forest interface for storage engine Signed-off-by: Evgenii Stratonikov --- pkg/local_object_storage/engine/tree.go | 78 +++++++++++++++++++++++ pkg/local_object_storage/shard/control.go | 6 +- pkg/local_object_storage/shard/shard.go | 5 ++ pkg/local_object_storage/shard/tree.go | 33 ++++++++++ 4 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 pkg/local_object_storage/engine/tree.go create mode 100644 pkg/local_object_storage/shard/tree.go diff --git a/pkg/local_object_storage/engine/tree.go b/pkg/local_object_storage/engine/tree.go new file mode 100644 index 000000000..986bea15e --- /dev/null +++ b/pkg/local_object_storage/engine/tree.go @@ -0,0 +1,78 @@ +package engine + +import ( + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/pilorama" + cidSDK "github.com/nspcc-dev/neofs-sdk-go/container/id" +) + +var _ pilorama.Forest = (*StorageEngine)(nil) + +// TreeMove implements the pilorama.Forest interface. +func (e *StorageEngine) TreeMove(cid cidSDK.ID, treeID string, m *pilorama.Move) (*pilorama.LogMove, error) { + var err error + var lm *pilorama.LogMove + for _, sh := range e.sortShardsByWeight(cid) { + lm, err = sh.TreeMove(cid, treeID, m) + if err != nil { + continue + } + return lm, nil + } + return nil, err +} + +// TreeAddByPath implements the pilorama.Forest interface. +func (e *StorageEngine) TreeAddByPath(cid cidSDK.ID, treeID string, attr string, path []string, m []pilorama.KeyValue) ([]pilorama.LogMove, error) { + var err error + var lm []pilorama.LogMove + for _, sh := range e.sortShardsByWeight(cid) { + lm, err = sh.TreeAddByPath(cid, treeID, attr, path, m) + if err != nil { + continue + } + return lm, nil + } + return nil, err +} + +// TreeApply implements the pilorama.Forest interface. +func (e *StorageEngine) TreeApply(cid cidSDK.ID, treeID string, m *pilorama.Move) error { + var err error + for _, sh := range e.sortShardsByWeight(cid) { + err = sh.TreeApply(cid, treeID, m) + if err != nil { + continue + } + return nil + } + + return err +} + +// TreeGetByPath implements the pilorama.Forest interface. +func (e *StorageEngine) TreeGetByPath(cid cidSDK.ID, treeID string, attr string, path []string, latest bool) ([]pilorama.Node, error) { + var err error + var nodes []pilorama.Node + for _, sh := range e.sortShardsByWeight(cid) { + nodes, err = sh.TreeGetByPath(cid, treeID, attr, path, latest) + if err != nil { + continue + } + return nodes, nil + } + return nil, err +} + +// TreeGetMeta implements the pilorama.Forest interface. +func (e *StorageEngine) TreeGetMeta(cid cidSDK.ID, treeID string, nodeID pilorama.Node) (pilorama.Meta, error) { + var err error + var m pilorama.Meta + for _, sh := range e.sortShardsByWeight(cid) { + m, err = sh.TreeGetMeta(cid, treeID, nodeID) + if err != nil { + continue + } + return m, nil + } + return pilorama.Meta{}, err +} diff --git a/pkg/local_object_storage/shard/control.go b/pkg/local_object_storage/shard/control.go index 1219fc817..1faf44aa0 100644 --- a/pkg/local_object_storage/shard/control.go +++ b/pkg/local_object_storage/shard/control.go @@ -15,7 +15,7 @@ import ( // Open opens all Shard's components. func (s *Shard) Open() error { components := []interface{ Open() error }{ - s.blobStor, s.metaBase, + s.blobStor, s.metaBase, s.pilorama, } if s.hasWriteCache() { @@ -41,7 +41,7 @@ func (s *Shard) Init() error { } components := []func() error{ - s.blobStor.Init, fMetabase, + s.blobStor.Init, fMetabase, s.pilorama.Init, } if s.hasWriteCache() { @@ -154,7 +154,7 @@ func (s *Shard) Close() error { components = append(components, s.writeCache) } - components = append(components, s.blobStor, s.metaBase) + components = append(components, s.pilorama, s.blobStor, s.metaBase) for _, component := range components { if err := component.Close(); err != nil { diff --git a/pkg/local_object_storage/shard/shard.go b/pkg/local_object_storage/shard/shard.go index 16aca5f15..f9f3a01f8 100644 --- a/pkg/local_object_storage/shard/shard.go +++ b/pkg/local_object_storage/shard/shard.go @@ -2,11 +2,13 @@ package shard import ( "context" + "path/filepath" "sync" "time" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor" meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/pilorama" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/writecache" "github.com/nspcc-dev/neofs-node/pkg/util" "github.com/nspcc-dev/neofs-node/pkg/util/logger" @@ -24,6 +26,8 @@ type Shard struct { blobStor *blobstor.BlobStor + pilorama pilorama.ForestStorage + metaBase *meta.DB tsSource TombstoneSource @@ -104,6 +108,7 @@ func New(opts ...Option) *Shard { metaBase: mb, writeCache: writeCache, tsSource: c.tsSource, + pilorama: pilorama.NewBoltForest(filepath.Join(bs.DumpInfo().RootPath, "pilorama.db")), } s.fillInfo() diff --git a/pkg/local_object_storage/shard/tree.go b/pkg/local_object_storage/shard/tree.go new file mode 100644 index 000000000..2a4120a12 --- /dev/null +++ b/pkg/local_object_storage/shard/tree.go @@ -0,0 +1,33 @@ +package shard + +import ( + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/pilorama" + cidSDK "github.com/nspcc-dev/neofs-sdk-go/container/id" +) + +var _ pilorama.Forest = (*Shard)(nil) + +// TreeMove implements the pilorama.Forest interface. +func (s *Shard) TreeMove(cid cidSDK.ID, treeID string, m *pilorama.Move) (*pilorama.LogMove, error) { + return s.pilorama.TreeMove(cid, treeID, m) +} + +// TreeAddByPath implements the pilorama.Forest interface. +func (s *Shard) TreeAddByPath(cid cidSDK.ID, treeID string, attr string, path []string, meta []pilorama.KeyValue) ([]pilorama.LogMove, error) { + return s.pilorama.TreeAddByPath(cid, treeID, attr, path, meta) +} + +// TreeApply implements the pilorama.Forest interface. +func (s *Shard) TreeApply(cid cidSDK.ID, treeID string, m *pilorama.Move) error { + return s.pilorama.TreeApply(cid, treeID, m) +} + +// TreeGetByPath implements the pilorama.Forest interface. +func (s *Shard) TreeGetByPath(cid cidSDK.ID, treeID string, attr string, path []string, latest bool) ([]pilorama.Node, error) { + return s.pilorama.TreeGetByPath(cid, treeID, attr, path, latest) +} + +// TreeGetMeta implements the pilorama.Forest interface. +func (s *Shard) TreeGetMeta(cid cidSDK.ID, treeID string, nodeID pilorama.Node) (pilorama.Meta, error) { + return s.pilorama.TreeGetMeta(cid, treeID, nodeID) +}