using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; namespace Beam.Models { public sealed class Fragment(int size) { public int Size => FragmentBag.Count; public int MaxSize { get; } = size; private ConcurrentBag FragmentBag { get; set; } = new(); public bool TryTake([NotNullWhen(true)] out T? shard) { return FragmentBag.TryTake(out shard) && shard != null; } private bool? Complete = false; public bool IsComplete => Complete ?? Size == MaxSize; private bool UpdaterLocked = false; public static bool TryAcquireUpdater(Fragment fragment, [NotNullWhen(true)] out Action? updater) { updater = null; if (Interlocked.CompareExchange(ref fragment.UpdaterLocked, true, false) == true) // equivalent to : fragment.UpdaterLocked == true, side-effect: sets fragment.UpdaterLocked to true return false; updater = fragment.FragmentBag.Add; return true; } public static bool TryReleaseUpdater(Fragment fragment, Action updater) { if (updater == fragment.FragmentBag.Add) { Interlocked.Exchange(ref fragment.UpdaterLocked, false); return true; } return false; } public static void SetComplete(Fragment fragment, bool status) { fragment.Complete = status; } } }