diff --git a/api/cache/objectslist.go b/api/cache/objectslist.go index 72f2a99c..403535c9 100644 --- a/api/cache/objectslist.go +++ b/api/cache/objectslist.go @@ -2,6 +2,7 @@ package cache import ( "fmt" + "strings" "time" "github.com/bluele/gcache" @@ -25,6 +26,7 @@ type ( ObjectsListCache interface { Get(key ObjectsListKey) []*object.ID Put(key ObjectsListKey, oids []*object.ID) error + CleanCacheEntriesContainingObject(objectName string, cid *cid.ID) } ) @@ -83,6 +85,21 @@ func (l *ListObjectsCache) Put(key ObjectsListKey, oids []*object.ID) error { return l.cache.SetWithExpire(key, oids, l.lifetime) } +// CleanCacheEntriesContainingObject deletes entries containing specified object. +func (l *ListObjectsCache) CleanCacheEntriesContainingObject(objectName string, cid *cid.ID) { + cidStr := cid.String() + keys := l.cache.Keys(true) + for _, key := range keys { + k, ok := key.(ObjectsListKey) + if !ok { + continue + } + if cidStr == k.cid && strings.HasPrefix(objectName, k.prefix) { + l.cache.Remove(k) + } + } +} + // CreateObjectsListCacheKey returns ObjectsListKey with given CID, method, prefix, and delimiter. func CreateObjectsListCacheKey(cid *cid.ID, prefix string) ObjectsListKey { p := ObjectsListKey{ diff --git a/api/layer/layer.go b/api/layer/layer.go index e11b39bc..5ae9e58a 100644 --- a/api/layer/layer.go +++ b/api/layer/layer.go @@ -632,6 +632,7 @@ func (n *layer) deleteObject(ctx context.Context, bkt *api.BucketInfo, obj *Vers return err } } + n.listsCache.CleanCacheEntriesContainingObject(obj.Name, bkt.CID) return nil } diff --git a/api/layer/object.go b/api/layer/object.go index 990b344c..85c96a6e 100644 --- a/api/layer/object.go +++ b/api/layer/object.go @@ -179,6 +179,8 @@ func (n *layer) objectPut(ctx context.Context, bkt *api.BucketInfo, p *PutObject n.log.Error("couldn't cache an object", zap.Error(err)) } + n.listsCache.CleanCacheEntriesContainingObject(p.Object, bkt.CID) + for _, id := range idsToDeleteArr { if err = n.objectDelete(ctx, bkt.CID, id); err != nil { n.log.Warn("couldn't delete object", @@ -503,13 +505,8 @@ func (n *layer) getAllObjectsVersions(ctx context.Context, bkt *api.BucketInfo, versions := make(map[string]*objectVersions, len(ids)/2) for i := 0; i < len(ids); i++ { - if ids[i] == nil { - continue - } obj := n.objectFromObjectsCacheOrNeoFS(ctx, bkt.CID, ids[i]) if obj == nil { - // mark ids[i] as an address of invalid object - ids[i] = nil continue } if oi := objectInfoFromMeta(bkt, obj, prefix, delimiter); oi != nil {