Exemple #1
0
            /// <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);
                    }