// Copyright Epic Games, Inc. All Rights Reserved. using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using EpicGames.Core; namespace EpicGames.Horde.Storage { /// /// Handle to a node. Can be used to reference nodes that have not been flushed yet. /// public interface IHashedBlobRef : IBlobRef { /// /// Hash of the target node /// IoHash Hash { get; } } /// /// Typed interface to a particular blob handle /// /// Type of the deserialized blob public interface IHashedBlobRef : IHashedBlobRef, IBlobRef { } /// /// Contains the value for a blob ref /// public record class HashedBlobRefValue(IoHash Hash, BlobLocator Locator); /// /// Helper methods for creating blob handles /// public static class HashedBlobRef { class HashedBlobRefImpl : IHashedBlobRef { readonly IoHash _hash; readonly IBlobRef _handle; public IBlobRef Innermost => _handle.Innermost; public IoHash Hash => _hash; public HashedBlobRefImpl(IoHash hash, IBlobRef handle) { _hash = hash; _handle = handle; } public ValueTask FlushAsync(CancellationToken cancellationToken = default) => _handle.FlushAsync(cancellationToken); public ValueTask ReadBlobDataAsync(CancellationToken cancellationToken = default) => _handle.ReadBlobDataAsync(cancellationToken); public bool TryGetLocator([NotNullWhen(true)] out BlobLocator locator) => _handle.TryGetLocator(out locator); } class HashedBlobRefImpl : HashedBlobRefImpl, IHashedBlobRef { readonly BlobSerializerOptions _options; public BlobSerializerOptions SerializerOptions => _options; public HashedBlobRefImpl(IoHash hash, IBlobRef handle, BlobSerializerOptions options) : base(hash, handle) { _options = options; } } /// /// Create an untyped blob handle /// /// Imported blob interface /// Hash of the blob /// Handle to the blob public static IHashedBlobRef Create(IoHash hash, IBlobRef handle) => new HashedBlobRefImpl(hash, handle); /// /// Create a typed blob handle /// /// /// Existing blob reference /// Options for deserializing the target blob /// Handle to the blob public static IHashedBlobRef Create(IHashedBlobRef blobRef, BlobSerializerOptions? options = null) => new HashedBlobRefImpl(blobRef.Hash, blobRef, options ?? BlobSerializerOptions.Default); /// /// Create a typed blob handle /// /// /// Hash of the blob /// Imported blob interface /// Options for deserializing the target blob /// Handle to the blob public static IHashedBlobRef Create(IoHash hash, IBlobRef handle, BlobSerializerOptions? options = null) => new HashedBlobRefImpl(hash, handle, options ?? BlobSerializerOptions.Default); } /// /// Extension methods for /// public static class HashedBlobRefExtensions { /// /// Gets a BlobRefValue from an IBlobRef /// public static HashedBlobRefValue GetRefValue(this IHashedBlobRef blobRef) { return new HashedBlobRefValue(blobRef.Hash, blobRef.GetLocator()); } } }