private IEnumerable <LoggedBinaryReaderRegion> Merge([NotNull] IEnumerable <LoggedBinaryReaderRegion> regions) { using (IEnumerator <LoggedBinaryReaderRegion> e = regions.GetEnumerator()) { if (!e.MoveNext()) { yield break; } long origin = e.Current.Position; long ending = e.Current.Position + e.Current.Length; while (e.MoveNext()) { LoggedBinaryReaderRegion current = e.Current; long currentPos = current.Position; long currentLen = current.Length; if (currentPos > ending) { yield return(new LoggedBinaryReaderRegion(origin, ending - origin)); origin = currentPos; ending = currentPos + currentLen; } else { ending = Math.Max(currentPos + currentLen, ending); } } yield return(new LoggedBinaryReaderRegion(origin, ending - origin)); } }
internal void EndGroupInternal() { if (Group == -1) { throw new InvalidOperationException($"A previous call to {nameof(BeginGroup)} has not been disposed."); } LoggedBinaryReaderRegion[] regions1 = Journal.Skip(Group).ToArray(); LoggedBinaryReaderRegion[] regions2 = Merge(regions1).ToArray(); if (regions2.Length > 1) { throw new NotSupportedException("Region grouping only supports consecutive regions."); } int count = Journal.Count - Group; for (int i = 0; i < count; i++) { Journal.RemoveAt(Journal.Count - 1); } LoggedBinaryReaderRegion region = regions2.First(); Journal.Add(region); Group = -1; }
/// <summary> /// Gets the regions that haven't been read. /// </summary> /// <returns> /// The unread regions. /// </returns> public IEnumerable <LoggedBinaryReaderRegion> GetUnreadRegions() { IEnumerable <LoggedBinaryReaderRegion> regions = Journal.GetOrderedRegions(); using (IEnumerator <LoggedBinaryReaderRegion> e = regions.GetEnumerator()) { // nothing at all if (!e.MoveNext()) { yield return(new LoggedBinaryReaderRegion(0, BaseStream.Length)); yield break; } LoggedBinaryReaderRegion first = e.Current; // beginning of file if (first.Position > 0) { yield return(new LoggedBinaryReaderRegion(0, first.Position)); } // middle of file while (e.MoveNext()) { LoggedBinaryReaderRegion second = e.Current; long secondPos = first.Position + first.Length; long secondLen = second.Position - secondPos; if (secondLen > 0) { yield return(new LoggedBinaryReaderRegion(secondPos, secondLen)); } first = second; } // end of file long thirdPos = first.Position + first.Length; long thirdLen = BaseStream.Length - thirdPos; if (thirdPos < BaseStream.Length) { yield return(new LoggedBinaryReaderRegion(thirdPos, thirdLen)); } } }