/// <summary> /// Loads the first available entries starting at a given time. /// </summary> /// <param name="firstLogTime">The first log time.</param> /// <param name="pageLength">The length of pages. Must be greater than 0.</param> /// <returns>The first <see cref="LivePage"/> from which next pages can be retrieved.</returns> public LivePage ReadFirstPage(DateTimeStamp firstLogTime, int pageLength) { Throw.CheckOutOfRangeArgument(pageLength > 0); MultiFileReader r = new MultiFileReader(firstLogTime, _files); if (r.MoveNext()) { return(new LivePage(_firstDepth, new ParentedLogEntry[pageLength], r, pageLength)); } return(new LivePage(_firstDepth, Array.Empty <ParentedLogEntry>(), null, pageLength)); }
/// <summary> /// Loads the first available entries starting at a given time. /// </summary> /// <param name="firstLogTime">The first log time.</param> /// <param name="pageLength">The length of pages. Must be greater than 0.</param> /// <returns>The first <see cref="LivePage"/> from which next pages can be retrieved.</returns> public LivePage ReadFirstPage(DateTimeStamp firstLogTime, int pageLength) { if (pageLength < 1) { throw new ArgumentOutOfRangeException("pageLength"); } MultiFileReader r = new MultiFileReader(firstLogTime, _files); if (r.MoveNext()) { return(new LivePage(_firstDepth, new ParentedLogEntry[pageLength], r, pageLength)); } return(new LivePage(_firstDepth, Util.Array.Empty <ParentedLogEntry>(), null, pageLength)); }
internal LivePage(int initialGroupDepth, ParentedLogEntry[] entries, MultiFileReader r, int pageLength) { Debug.Assert(pageLength == entries.Length || entries.Length == 0); _r = r; _pageLength = pageLength; _currentPath = new List <ParentedLogEntry>(); ParentedLogEntry e = null; for (int i = 0; i < initialGroupDepth; ++i) { ParentedLogEntry g = new ParentedLogEntry(e, LogEntry.CreateMissingOpenGroup(DateTimeStamp.Unknown)); _currentPath.Add(g); e = g; } _entries = new WrappedList(entries); if (_r != null) { _entries.FillPage(_r, _currentPath); } }
int DoFillPage(MultiFileReader r, List <ParentedLogEntry> path, ILogEntry lastPrevEntry) { ParentedLogEntry parent = path.Count > 0 ? path[path.Count - 1] : null; int i = 0; do { var entry = r.Current; if (entry.GroupDepth < path.Count) { // Adds a MissingCloseGroup with an unknown time for tail groups: handles the // last closing group specifically. while (entry.GroupDepth < path.Count - 1) { if (AppendEntry(path, ref parent, ref i, LogEntry.CreateMissingCloseGroup(DateTimeStamp.Unknown))) { return(i); } } // Handles the last auto-close group: we may know its time thanks to our current entry (if its previous type is a CloseGroup). Debug.Assert(entry.GroupDepth == path.Count - 1, "We are on the last group to auto-close."); DateTimeStamp prevTime = entry.PreviousEntryType == LogEntryType.CloseGroup ? entry.PreviousLogTime : DateTimeStamp.Unknown; if (AppendEntry(path, ref parent, ref i, LogEntry.CreateMissingCloseGroup(prevTime))) { return(i); } } else if (entry.GroupDepth > path.Count) { // Adds a MissingOpenGroup with an unknown time for head groups: handles the // last opening group specifically. while (entry.GroupDepth > path.Count + 1) { if (AppendEntry(path, ref parent, ref i, LogEntry.CreateMissingOpenGroup(DateTimeStamp.Unknown))) { return(i); } } // Handles the last auto-open group: we may know its time thanks to our current entry (if its previous type is a OpenGroup). Debug.Assert(entry.GroupDepth == path.Count + 1, "We are on the last group to auto-open."); DateTimeStamp prevTime = entry.PreviousEntryType == LogEntryType.OpenGroup ? entry.PreviousLogTime : DateTimeStamp.Unknown; if (AppendEntry(path, ref parent, ref i, LogEntry.CreateMissingOpenGroup(prevTime))) { return(i); } } // If we know the the time and type of the previous entry and this does not correspond to // our predecessor, we inject a missing line. // This is necessarily a line that we inject here thanks to the open/close adjustment above. // If the log type of the known previous entry is Open or Close group, it means that there are incoherent group depths... and // we ignore this pathological case. if (entry.PreviousEntryType != LogEntryType.None) { ILogEntry prevEntry = i > 0 ? Entries[i - 1].Entry : lastPrevEntry; if (prevEntry == null || prevEntry.LogTime != entry.PreviousLogTime) { if (AppendEntry(path, ref parent, ref i, LogEntry.CreateMissingLine(entry.PreviousLogTime))) { return(i); } } } // Now that missing data has been handled, appends the line itself. if (AppendEntry(path, ref parent, ref i, entry.CreateUnicastLogEntry())) { return(i); } }while(r.MoveNext()); return(i); }
internal void FillPage(MultiFileReader r, List <ParentedLogEntry> path) { ILogEntry lastPrevEntry = Count > 0 ? Entries[Count - 1].Entry : null; Count = DoFillPage(r, path, lastPrevEntry); }