package writecache import ( "context" "errors" "math" "time" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" storagelog "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/log" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr" "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" "github.com/cockroachdb/pebble" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) // Delete removes object from write-cache. // // Returns an error of type apistatus.ObjectNotFound if object is missing in write-cache. // Returns ErrNotInitialized if write-cache has not been initialized yet. // Returns ErrDegraded if write-cache is in DEGRADED mode. func (c *cache) Delete(ctx context.Context, addr oid.Address) error { ctx, span := tracing.StartSpanFromContext(ctx, "writecache.Delete", trace.WithAttributes( attribute.String("address", addr.EncodeToString()), )) defer span.End() deleted := false storageType := StorageTypeUndefined startedAt := time.Now() defer func() { c.metrics.Delete(time.Since(startedAt), deleted, storageType) }() if !c.modeMtx.TryRLock() { return ErrNotInitialized } defer c.modeMtx.RUnlock() if c.readOnly() { return ErrReadOnly } if c.noMetabase() { return ErrDegraded } saddr := addr.EncodeToString() c.dbEditLocker.Lock(saddr) defer func() { c.dbEditLocker.Unlock(saddr) }() dbKey := []byte(saddr) var dataSize int data, closer, err := c.db.Get(dbKey) if err == nil { dataSize = len(data) err = closer.Close() } if err != nil && !errors.Is(err, pebble.ErrNotFound) { return err } if dataSize > 0 { storageType = StorageTypeDB var recordDeleted bool err := c.db.DeleteSized(dbKey, uint32(dataSize), pebble.Sync) if err != nil { return err } storagelog.Write(c.log, storagelog.AddressField(saddr), storagelog.StorageTypeField(wcStorageType), storagelog.OpField("db DELETE"), ) if recordDeleted { c.objCounters.cDB.Add(math.MaxUint64) c.estimateCacheSize() } deleted = true return nil } storageType = StorageTypeFSTree _, err = c.fsTree.Delete(ctx, common.DeletePrm{Address: addr}) if err == nil { storagelog.Write(c.log, storagelog.AddressField(saddr), storagelog.StorageTypeField(wcStorageType), storagelog.OpField("fstree DELETE"), ) deleted = true // counter changed by fstree c.estimateCacheSize() } return metaerr.Wrap(err) }