forked from TrueCloudLab/frostfs-node
[#5] blobstor: Use generic LRU cache
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
parent
f0be0befc5
commit
9936b112b8
5 changed files with 13 additions and 15 deletions
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
"github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/TrueCloudLab/hrw"
|
"github.com/TrueCloudLab/hrw"
|
||||||
"github.com/hashicorp/golang-lru/simplelru"
|
"github.com/hashicorp/golang-lru/v2/simplelru"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ type Blobovniczas struct {
|
||||||
cfg
|
cfg
|
||||||
|
|
||||||
// cache of opened filled Blobovniczas
|
// cache of opened filled Blobovniczas
|
||||||
opened *simplelru.LRU
|
opened *simplelru.LRU[string, *blobovnicza.Blobovnicza]
|
||||||
// lruMtx protects opened cache.
|
// lruMtx protects opened cache.
|
||||||
// It isn't RWMutex because `Get` calls must
|
// It isn't RWMutex because `Get` calls must
|
||||||
// lock this mutex on write, as LRU info is updated.
|
// lock this mutex on write, as LRU info is updated.
|
||||||
|
@ -97,21 +97,20 @@ func NewBlobovniczaTree(opts ...Option) (blz *Blobovniczas) {
|
||||||
opts[i](&blz.cfg)
|
opts[i](&blz.cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
cache, err := simplelru.NewLRU(blz.openedCacheSize, func(key interface{}, value interface{}) {
|
cache, err := simplelru.NewLRU[string, *blobovnicza.Blobovnicza](blz.openedCacheSize, func(p string, value *blobovnicza.Blobovnicza) {
|
||||||
p := key.(string)
|
|
||||||
lvlPath := filepath.Dir(p)
|
lvlPath := filepath.Dir(p)
|
||||||
if b, ok := blz.active[lvlPath]; ok && b.ind == u64FromHexString(filepath.Base(p)) {
|
if b, ok := blz.active[lvlPath]; ok && b.ind == u64FromHexString(filepath.Base(p)) {
|
||||||
// This branch is taken if we have recently updated active blobovnicza and remove
|
// This branch is taken if we have recently updated active blobovnicza and remove
|
||||||
// it from opened cache.
|
// it from opened cache.
|
||||||
return
|
return
|
||||||
} else if err := value.(*blobovnicza.Blobovnicza).Close(); err != nil {
|
} else if err := value.Close(); err != nil {
|
||||||
blz.log.Error("could not close Blobovnicza",
|
blz.log.Error("could not close Blobovnicza",
|
||||||
zap.String("id", key.(string)),
|
zap.String("id", p),
|
||||||
zap.String("error", err.Error()),
|
zap.String("error", err.Error()),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
blz.log.Debug("blobovnicza successfully closed on evict",
|
blz.log.Debug("blobovnicza successfully closed on evict",
|
||||||
zap.String("id", key.(string)),
|
zap.String("id", p),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -57,11 +57,10 @@ func (b *Blobovniczas) Close() error {
|
||||||
b.opened.Remove(p)
|
b.opened.Remove(p)
|
||||||
}
|
}
|
||||||
for _, k := range b.opened.Keys() {
|
for _, k := range b.opened.Keys() {
|
||||||
v, _ := b.opened.Get(k)
|
blz, _ := b.opened.Get(k)
|
||||||
blz := v.(*blobovnicza.Blobovnicza)
|
|
||||||
if err := blz.Close(); err != nil {
|
if err := blz.Close(); err != nil {
|
||||||
b.log.Debug("could not close active blobovnicza",
|
b.log.Debug("could not close active blobovnicza",
|
||||||
zap.String("path", k.(string)),
|
zap.String("path", k),
|
||||||
zap.String("error", err.Error()),
|
zap.String("error", err.Error()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -86,7 +85,7 @@ func (b *Blobovniczas) openBlobovnicza(p string) (*blobovnicza.Blobovnicza, erro
|
||||||
b.lruMtx.Unlock()
|
b.lruMtx.Unlock()
|
||||||
if ok {
|
if ok {
|
||||||
// blobovnicza should be opened in cache
|
// blobovnicza should be opened in cache
|
||||||
return v.(*blobovnicza.Blobovnicza), nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
lvlPath := filepath.Dir(p)
|
lvlPath := filepath.Dir(p)
|
||||||
|
@ -105,7 +104,7 @@ func (b *Blobovniczas) openBlobovnicza(p string) (*blobovnicza.Blobovnicza, erro
|
||||||
|
|
||||||
v, ok = b.opened.Get(p)
|
v, ok = b.opened.Get(p)
|
||||||
if ok {
|
if ok {
|
||||||
return v.(*blobovnicza.Blobovnicza), nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
blz, err := b.openBlobovniczaNoCache(p)
|
blz, err := b.openBlobovniczaNoCache(p)
|
||||||
|
|
|
@ -80,7 +80,7 @@ func (b *Blobovniczas) deleteObjectFromLevel(prm blobovnicza.DeletePrm, blzPath
|
||||||
v, ok := b.opened.Get(blzPath)
|
v, ok := b.opened.Get(blzPath)
|
||||||
b.lruMtx.Unlock()
|
b.lruMtx.Unlock()
|
||||||
if ok {
|
if ok {
|
||||||
if res, err := b.deleteObject(v.(*blobovnicza.Blobovnicza), prm, dp); err == nil {
|
if res, err := b.deleteObject(v, prm, dp); err == nil {
|
||||||
return res, err
|
return res, err
|
||||||
} else if !blobovnicza.IsErrNotFound(err) {
|
} else if !blobovnicza.IsErrNotFound(err) {
|
||||||
b.log.Debug("could not remove object from opened blobovnicza",
|
b.log.Debug("could not remove object from opened blobovnicza",
|
||||||
|
|
|
@ -72,7 +72,7 @@ func (b *Blobovniczas) getObjectFromLevel(prm blobovnicza.GetPrm, blzPath string
|
||||||
v, ok := b.opened.Get(blzPath)
|
v, ok := b.opened.Get(blzPath)
|
||||||
b.lruMtx.Unlock()
|
b.lruMtx.Unlock()
|
||||||
if ok {
|
if ok {
|
||||||
if res, err := b.getObject(v.(*blobovnicza.Blobovnicza), prm); err == nil {
|
if res, err := b.getObject(v, prm); err == nil {
|
||||||
return res, err
|
return res, err
|
||||||
} else if !blobovnicza.IsErrNotFound(err) {
|
} else if !blobovnicza.IsErrNotFound(err) {
|
||||||
b.log.Debug("could not read object from opened blobovnicza",
|
b.log.Debug("could not read object from opened blobovnicza",
|
||||||
|
|
|
@ -76,7 +76,7 @@ func (b *Blobovniczas) getRangeFromLevel(prm common.GetRangePrm, blzPath string,
|
||||||
v, ok := b.opened.Get(blzPath)
|
v, ok := b.opened.Get(blzPath)
|
||||||
b.lruMtx.Unlock()
|
b.lruMtx.Unlock()
|
||||||
if ok {
|
if ok {
|
||||||
res, err := b.getObjectRange(v.(*blobovnicza.Blobovnicza), prm)
|
res, err := b.getObjectRange(v, prm)
|
||||||
switch {
|
switch {
|
||||||
case err == nil,
|
case err == nil,
|
||||||
isErrOutOfRange(err):
|
isErrOutOfRange(err):
|
||||||
|
|
Loading…
Reference in a new issue