private static AddRangeOnList <TObject, T> _maybeInstance; // cache and reuse or discard public static void Populate(List <T> list, TObject obj, Containers.GetSpan <TObject, T> getSpan) { var listPopulator = Interlocked.Exchange(ref _maybeInstance, null); if (listPopulator == null) { listPopulator = new AddRangeOnList <TObject, T>(); } listPopulator.obj = obj; listPopulator.getSpan = getSpan; list.AddRange(listPopulator); listPopulator.obj = default; listPopulator.getSpan = null; _maybeInstance = listPopulator; // might splat another, might not get flushed in time, but we don't care }
private static BatchProcessResult TryProcessBatch <T, TObject, T2U>(TObject obj, Containers.GetSpan <TObject, T> getSpan, ref T2U forwardEnumerator, ref bool moreData) where T2U : IPushEnumerator <T> { if (!moreData) { return(BatchProcessResult.SuccessAndHalt); } var uResult = forwardEnumerator.TryProcessBatch <TObject, Containers.GetSpan <TObject, T> >(obj, getSpan); if (uResult == BatchProcessResult.SuccessAndHalt) { moreData = false; } return(uResult); }
internal static BatchProcessResult ProcessBatch <TElement, TObject, TPushEnumerator1, TPushEnumerator2>(TObject obj, Containers.GetSpan <TObject, TElement> getSpan, ref TPushEnumerator1 t2u, ref bool t2uMoreData, ref TPushEnumerator2 t2v, ref bool t2vMoreData) where TPushEnumerator1 : IPushEnumerator <TElement> where TPushEnumerator2 : IPushEnumerator <TElement> { var uResult = TryProcessBatch <TElement, TObject, TPushEnumerator1>(obj, getSpan, ref t2u, ref t2uMoreData); var vResult = TryProcessBatch <TElement, TObject, TPushEnumerator2>(obj, getSpan, ref t2v, ref t2vMoreData); if (!t2uMoreData && !t2vMoreData) { return(BatchProcessResult.SuccessAndHalt); } else if (uResult != BatchProcessResult.Unavailable && vResult != BatchProcessResult.Unavailable) { return(BatchProcessResult.SuccessAndContinue); } var span = getSpan(obj); if (uResult == BatchProcessResult.Unavailable) { t2uMoreData = ProcessSpan(span, ref t2u); } if (vResult == BatchProcessResult.Unavailable) { t2vMoreData = ProcessSpan(span, ref t2v); } if (!t2uMoreData && !t2vMoreData) { return(BatchProcessResult.SuccessAndHalt); } return(BatchProcessResult.SuccessAndContinue); }