package blobtree import ( "context" "errors" "time" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) func (b *BlobTree) Exists(ctx context.Context, prm common.ExistsPrm) (common.ExistsRes, error) { var ( startedAt = time.Now() success = false ) defer func() { b.cfg.metrics.Exists(time.Since(startedAt), success, prm.StorageID != nil) }() _, span := tracing.StartSpanFromContext(ctx, "BlobTree.Exists", trace.WithAttributes( attribute.String("path", b.cfg.rootPath), attribute.String("address", prm.Address.EncodeToString()), attribute.String("storage_id", string(prm.StorageID)), )) defer span.End() var res common.ExistsRes var err error if path, ok := getPathFromStorageID(prm.StorageID); ok { res, err = b.existsFromPath(prm.Address, path) } else { res, err = b.findAndCheckExistance(prm.Address) } success = err == nil return res, err } func (b *BlobTree) existsFromPath(addr oid.Address, path string) (common.ExistsRes, error) { b.fileLock.RLock(path) defer b.fileLock.RUnlock(path) records, err := b.readFileContent(path) if err != nil { return common.ExistsRes{}, err } for i := range records { if records[i].Address.Equals(addr) { return common.ExistsRes{ Exists: true, }, nil } } return common.ExistsRes{}, nil } func (b *BlobTree) findAndCheckExistance(addr oid.Address) (common.ExistsRes, error) { dir := b.getDir(addr) _, err := b.findFileIdx(dir, addr) if err == nil { return common.ExistsRes{Exists: true}, nil } var notFound *apistatus.ObjectNotFound if errors.As(err, ¬Found) { return common.ExistsRes{}, nil } return common.ExistsRes{}, err }