public IEnumerable <MergingCollectionEntry> Forward(int startPos, int endPosition) { Lock(); try { int totalCount = 0; var queueComparer = new QueueEntriesComparer(reverse: false); var queue = new VCSKicksCollection.PriorityQueue <QueueEntry>(queueComparer); try { int collectionsCount = 0; foreach (IMessagesCollection l in GetCollectionsToMerge()) { ++collectionsCount; int localCount = l.Count; totalCount += localCount; IEnumerator <IndexedMessage> i = l.Forward(0, localCount).GetEnumerator(); if (i.MoveNext()) { queue.Enqueue(new QueueEntry(i, l)); } } startPos = RangeUtils.PutInRange(0, totalCount, startPos); endPosition = RangeUtils.PutInRange(0, totalCount, endPosition); if (collectionsCount == 1) // optimized version for the case when there is only one collection to merge { var entry = queue.Dequeue(); using (IEnumerator <IndexedMessage> i = entry.enumerator) { for (int idx = 0; idx < endPosition; ++idx) { if (idx >= startPos) { yield return(new MergingCollectionEntry( new IndexedMessage(idx, i.Current.Message), entry.collection, i.Current.Index)); } if (!i.MoveNext()) { break; } } } } else { for (int idx = 0; idx < endPosition; ++idx) { var entry = queue.Dequeue(); var i = entry.enumerator; try { if (idx >= startPos) { yield return(new MergingCollectionEntry( new IndexedMessage(idx, i.Current.Message), entry.collection, i.Current.Index)); } if (i.MoveNext()) { queue.Enqueue(entry); i = null; } } finally { if (i != null) { i.Dispose(); } } } } } finally { while (queue.Count != 0) { queue.Dequeue().enumerator.Dispose(); } } } finally { Unlock(); } }
public IEnumerable <MergingCollectionEntry> Reverse(int startPos, int endPosition) { Lock(); try { var queueComparer = new QueueEntriesComparer(reverse: true); var queue = new VCSKicksCollection.PriorityQueue <QueueEntry>(queueComparer); try { int collectionsCount = 0; int c = 0; foreach (IMessagesCollection l in GetCollectionsToMerge()) { ++collectionsCount; int lc = l.Count; c += lc; IEnumerator <IndexedMessage> i = l.Reverse(lc - 1, -1).GetEnumerator(); if (i.MoveNext()) { queue.Enqueue(new QueueEntry(i, l)); } } startPos = RangeUtils.PutInRange(-1, c - 1, startPos); endPosition = RangeUtils.PutInRange(-1, c - 1, endPosition); for (int idx = c - 1; idx > endPosition; --idx) { var entry = queue.Dequeue(); var i = entry.enumerator; try { if (idx <= startPos) { yield return(new MergingCollectionEntry( new IndexedMessage(idx, i.Current.Message), entry.collection, i.Current.Index)); } if (i.MoveNext()) { queue.Enqueue(entry); i = null; } } finally { if (i != null) { i.Dispose(); } } } } finally { while (queue.Count != 0) { queue.Dequeue().enumerator.Dispose(); } } } finally { Unlock(); } }