[#231] cache: Add invalidation of ListObjectsCache

In put operations ListObjectsCache remove entries which can contain
put object

Signed-off-by: Angira Kekteeva <kira@nspcc.ru>
This commit is contained in:
Angira Kekteeva 2021-09-01 19:10:52 +03:00 committed by Alex Vanin
parent 1ece42b23f
commit be08596c22
3 changed files with 20 additions and 5 deletions

View file

@ -2,6 +2,7 @@ package cache
import ( import (
"fmt" "fmt"
"strings"
"time" "time"
"github.com/bluele/gcache" "github.com/bluele/gcache"
@ -25,6 +26,7 @@ type (
ObjectsListCache interface { ObjectsListCache interface {
Get(key ObjectsListKey) []*object.ID Get(key ObjectsListKey) []*object.ID
Put(key ObjectsListKey, oids []*object.ID) error 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) 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. // CreateObjectsListCacheKey returns ObjectsListKey with given CID, method, prefix, and delimiter.
func CreateObjectsListCacheKey(cid *cid.ID, prefix string) ObjectsListKey { func CreateObjectsListCacheKey(cid *cid.ID, prefix string) ObjectsListKey {
p := ObjectsListKey{ p := ObjectsListKey{

View file

@ -632,6 +632,7 @@ func (n *layer) deleteObject(ctx context.Context, bkt *api.BucketInfo, obj *Vers
return err return err
} }
} }
n.listsCache.CleanCacheEntriesContainingObject(obj.Name, bkt.CID)
return nil return nil
} }

View file

@ -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.log.Error("couldn't cache an object", zap.Error(err))
} }
n.listsCache.CleanCacheEntriesContainingObject(p.Object, bkt.CID)
for _, id := range idsToDeleteArr { for _, id := range idsToDeleteArr {
if err = n.objectDelete(ctx, bkt.CID, id); err != nil { if err = n.objectDelete(ctx, bkt.CID, id); err != nil {
n.log.Warn("couldn't delete object", 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) versions := make(map[string]*objectVersions, len(ids)/2)
for i := 0; i < len(ids); i++ { for i := 0; i < len(ids); i++ {
if ids[i] == nil {
continue
}
obj := n.objectFromObjectsCacheOrNeoFS(ctx, bkt.CID, ids[i]) obj := n.objectFromObjectsCacheOrNeoFS(ctx, bkt.CID, ids[i])
if obj == nil { if obj == nil {
// mark ids[i] as an address of invalid object
ids[i] = nil
continue continue
} }
if oi := objectInfoFromMeta(bkt, obj, prefix, delimiter); oi != nil { if oi := objectInfoFromMeta(bkt, obj, prefix, delimiter); oi != nil {