public void UpdateLineNumbers(ILogFile logFile, LogFileSection visibleSection, double yOffset) { int lineNumberCharacterCount; if (logFile != null) { lineNumberCharacterCount = (int)Math.Ceiling(Math.Log10(logFile.Count)); } else { lineNumberCharacterCount = 0; } // We always reserve space for at least 3 characters. _lineNumberWidth = TextHelper.EstimateWidthUpperLimit(Math.Max(lineNumberCharacterCount, 3)); Width = _lineNumberWidth + TextHelper.LineNumberSpacing; _yOffset = yOffset; _lineNumbers.Clear(); for (int i = 0; i < visibleSection.Count; ++i) { _lineNumbers.Add(new LineNumber(visibleSection.Index + i)); } InvalidateVisual(); }
public void Invalidate(int firstIndex, int count) { int lastIndex = Math.Min(firstIndex + count, _lastNumberOfLines); int invalidateCount = lastIndex - firstIndex; // When the start index of the invalidation is greater than the last reported index // then this means that our listeners haven't even gotten the change yet and thus // they don't need to be notified of the invalidation either. if (invalidateCount > 0) { var section = new LogFileSection(firstIndex, invalidateCount, true); _listener.OnLogFileModified(_logFile, section); _lastNumberOfLines = firstIndex; } }
public void TestManyEntries5() { var logFile = new MultiLineLogFile(_taskScheduler, _source.Object, TimeSpan.Zero); _lines.Add(new LogLine(0, 0, "Foo", LevelFlags.Other)); _lines.Add(new LogLine(1, 1, "Bar", LevelFlags.Other)); _lines.Add(new LogLine(2, 2, "INFO: Sup", LevelFlags.Info)); logFile.OnLogFileModified(_source.Object, new LogFileSection(0, 3)); logFile.OnLogFileModified(_source.Object, LogFileSection.Invalidate(1, 2)); logFile.OnLogFileModified(_source.Object, new LogFileSection(1, 2)); _taskScheduler.RunOnce(); logFile.Count.Should().Be(3); var entries = logFile.GetSection(new LogFileSection(0, 3)); entries.Should().Equal(new object[] { new LogLine(0, 0, "Foo", LevelFlags.Other), new LogLine(1, 0, "Bar", LevelFlags.Other), new LogLine(2, 1, "INFO: Sup", LevelFlags.Info) }); }
public void TestListen3() { using (var proxy = new LogFileProxy(_scheduler, TimeSpan.Zero, _logFile.Object)) { proxy.AddListener(_listener.Object, TimeSpan.Zero, 1000); _listeners.OnRead(500); _listeners.Invalidate(400, 100); _listeners.OnRead(550); _scheduler.RunOnce(); _modifications.Should().Equal(new[] { LogFileSection.Reset, new LogFileSection(0, 500), LogFileSection.Invalidate(400, 100), new LogFileSection(400, 150) }); } }
public void TestOneEntry3() { var logFile = new MultiLineLogFile(_taskScheduler, _source.Object, TimeSpan.Zero); logFile.AddListener(_listener.Object, TimeSpan.Zero, 10); _lines.Add(new LogLine(0, 0, "INFO: hello", LevelFlags.Info)); logFile.OnLogFileModified(_source.Object, new LogFileSection(0, 1)); _taskScheduler.RunOnce(); _changes.Should().Equal(new object[] { LogFileSection.Reset, new LogFileSection(0, 1) }); _changes.Clear(); _lines.Add(new LogLine(1, 1, "world!", LevelFlags.None)); logFile.OnLogFileModified(_source.Object, new LogFileSection(1, 1)); _taskScheduler.RunOnce(); _changes.Should().Equal(new object[] { LogFileSection.Invalidate(0, 1), new LogFileSection(0, 2) }); }
private void Add(ILogFile logFile, LogFileSection section) { // !!!We deliberately retrieve this section OUTSIDE of our own lock!!! logFile.GetEntries(section, _buffer); // Calculating the max width of a line takes time and is therefore done outside // the lock! var indices = new List <ILogEntry>(section.Count); for (var i = 0; i < section.Count; ++i) { var logEntry = _buffer[i]; indices.Add(CreateIndex(logEntry)); } lock (_syncRoot) { if (!ReferenceEquals(logFile, _source)) { // We've retrieved data from a different log file than we wanted to... Log.WarnFormat("Ignoring add '{0}': It's probably from a previous log file", section); } else { foreach (var index in indices) { if (_indices.Count > 0) { var last = _indices[_indices.Count - 1]; var maxWidth = last.GetValue(LogFileColumns.PresentationStartingLineNumber) + last.GetValue(LogFileColumns.PresentationLineCount); index.SetValue(LogFileColumns.PresentationStartingLineNumber, maxWidth); } _indices.Add(index); _maxWidth = Math.Max(_maxWidth, index.GetValue(LogFileColumns.RawContentMaxPresentationWidth)); _lineCount += index.GetValue(LogFileColumns.PresentationLineCount); } } } }
private void GetDeltaTime(LogFileSection section, TimeSpan?[] buffer, int destinationIndex) { var actualIndices = new LogLineIndex[section.Count + 1]; lock (_indices) { var startIndex = section.Index; if (startIndex > 0) { actualIndices[0] = _indices[startIndex - 1]; } else { actualIndices[0] = -1; } for (int i = 0; i < section.Count; ++i) { var filteredIndex = (startIndex + i).Value; if (filteredIndex >= 0 && filteredIndex < _indices.Count) { actualIndices[i + 1] = _indices[filteredIndex]; } else { actualIndices[i + 1] = -1; } } } var timestamps = _source.GetColumn(actualIndices, LogFileColumns.Timestamp); for (int i = 1; i <= section.Count; ++i) { var previousTimestamp = timestamps[i - 1]; var currentTimestamp = timestamps[i]; var delta = currentTimestamp - previousTimestamp; buffer[destinationIndex + i - 1] = delta; } }
private void Update(ILogFile logFile, LogFileSection section) { try { if (section.IsReset) { Clear(logFile); } else if (section.IsInvalidate) { InvalidateFrom(logFile, section.Index); } else { Add(logFile, section); } } catch (Exception e) { Log.ErrorFormat("Caught unexpected exception: {0}", e); } }
public void TestInvalidate2() { using (var file = new FilteredLogFile(_taskScheduler, TimeSpan.Zero, _logFile.Object, null, Filter.Create(null, true, LevelFlags.Info))) { file.AddListener(_listener.Object, TimeSpan.Zero, 1); _taskScheduler.RunOnce(); file.EndOfSourceReached.Should().BeTrue(); _entries.AddRange(new[] { new LogLine(0, 0, "A", LevelFlags.Info), new LogLine(1, 1, "B", LevelFlags.Info), new LogLine(2, 2, "C", LevelFlags.Info), new LogLine(3, 3, "D", LevelFlags.Info) }); file.OnLogFileModified(_logFile.Object, new LogFileSection(0, 4)); _taskScheduler.RunOnce(); file.EndOfSourceReached.Should().BeTrue(); file.Count.Should().Be(4); file.OnLogFileModified(_logFile.Object, LogFileSection.Invalidate(2, 2)); _taskScheduler.RunOnce(); file.EndOfSourceReached.Should().BeTrue(); file.Count.Should().Be(2); _sections.Should().Equal(new[] { LogFileSection.Reset, new LogFileSection(0, 1), new LogFileSection(1, 1), new LogFileSection(2, 1), new LogFileSection(3, 1), LogFileSection.Invalidate(2, 2) }); } }
public void TestAppendTwoSourcesWrongOrderSeparateChangesFullInvalidation() { var source1 = new InMemoryLogFile(); source1.AddEntry("B", LevelFlags.None, new DateTime(2019, 5, 27, 23, 10, 0)); var source2 = new InMemoryLogFile(); source2.AddEntry("A", LevelFlags.None, new DateTime(2019, 5, 27, 23, 09, 0)); var index = new MergedLogFileIndex(source1, source2); var changes = index.Process(new MergedLogFilePendingModification(source1, new LogFileSection(0, 1))); changes.Should().Equal(new object[] { new LogFileSection(0, 1) }); changes = index.Process(new MergedLogFilePendingModification(source2, new LogFileSection(0, 1))); changes.Should().Equal(new object[] { LogFileSection.Invalidate(0, 1), new LogFileSection(0, 2) }); var indices = index.Get(new LogFileSection(0, 2)); indices.Count.Should().Be(2); indices[0].LogFileIndex.Should().Be(1); indices[0].SourceLineIndex.Should().Be(0); indices[0].OriginalLogEntryIndex.Should().Be(0); indices[0].MergedLogEntryIndex.Should().Be(0); indices[0].Timestamp.Should().Be(new DateTime(2019, 5, 27, 23, 9, 0)); indices[1].LogFileIndex.Should().Be(0); indices[1].SourceLineIndex.Should().Be(0); indices[1].OriginalLogEntryIndex.Should().Be(0); indices[1].MergedLogEntryIndex.Should().Be(1); indices[1].Timestamp.Should().Be(new DateTime(2019, 5, 27, 23, 10, 0)); }
public void TestReadAll2() { using (var file = new TextLogFile(_scheduler, File20Mb)) { var listener = new Mock <ILogFileListener>(); var sections = new List <LogFileSection>(); listener.Setup(x => x.OnLogFileModified(It.IsAny <ILogFile>(), It.IsAny <LogFileSection>())) .Callback((ILogFile logFile, LogFileSection section) => sections.Add(section)); file.AddListener(listener.Object, TimeSpan.Zero, 1); file.Property(x => x.EndOfSourceReached).ShouldAfter(TimeSpan.FromSeconds(20)).BeTrue(); file.Count.Should().Be(165342); sections[0].Should().Equal(LogFileSection.Reset); for (int i = 1; i < sections.Count; ++i) { LogFileSection change = sections[i]; change.Index.Should().Be((LogLineIndex)(i - 1)); change.Count.Should().Be(1); } } }
/// <summary> /// Fetches the newest values for this presenter's column from the given log file. /// </summary> /// <param name="logFile"></param> /// <param name="visibleSection"></param> /// <param name="yOffset"></param> public void FetchValues(ILogFile logFile, LogFileSection visibleSection, double yOffset) { if (Visibility != Visibility.Visible) //< We shouldn't waste CPU cycles when we're hidden from view... { return; } _yOffset = yOffset; _values.Clear(); if (logFile != null) { var values = new T[visibleSection.Count]; logFile.GetColumn(visibleSection, _column, values); foreach (var value in values) { _values.Add(CreatePresenter(value)); } } UpdateWidth(logFile); InvalidateVisual(); }
public string ExtractLogFile(string cffFilename, string line, Validations validations) { string EXPECTED_LOGFILE_FORMAT = $"\"[name].{LOGFILE_EXTENSION}\""; // Check whether the line starts opening/closing LOGFILE section // If yes, mark it exist LogFileSection.MarkSection(line, Int16.Parse(validations.LineNumber)); bool openingSectionVisited = LogFileSection.ValidSectionPair[0]; // Check the line start with the expected keyword, "DEFAULT" if (openingSectionVisited && line.StartsWith(CffKeywords.DEFAULT_LOGFILE)) { // Check whether the pair key-value exists string[] lineData = validations.CheckPairKeyValue( line, CffKeywords.DEFAULT_LOGFILE, EXPECTED_LOGFILE_FORMAT); if (lineData != null) { LogFile = validations.CheckTextValueExist( lineData[1], LogFile, EXPECTED_LOGFILE_FORMAT); } } // Check whether the value in the above pair has the valid extension (.text), // and check the filename has no invalia file character bool logfileExtensionValid = LogFile != null && validations.CheckExtension(LogFile, LOGFILE_EXTENSION); bool noInvalidFilenameChars = logfileExtensionValid && validations.CheckInvalidFileNameChars(LogFile); return(LogFile); }
/// <inheritdoc /> public override void GetColumn <T>(LogFileSection section, ILogFileColumn <T> column, T[] buffer, int destinationIndex) { if (column == null) { throw new ArgumentNullException(nameof(column)); } if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (destinationIndex < 0) { throw new ArgumentOutOfRangeException(nameof(destinationIndex)); } if (destinationIndex + section.Count > buffer.Length) { throw new ArgumentException("The given buffer must have an equal or greater length than destinationIndex+length"); } if (Equals(column, LogFileColumns.DeltaTime)) { GetDeltaTime(section, (TimeSpan?[])(object)buffer, destinationIndex); } else if (Equals(column, LogFileColumns.LineNumber)) { GetLineNumber(section, (int[])(object)buffer, destinationIndex); } else if (Equals(column, LogFileColumns.OriginalIndex)) { GetOriginalIndices(section, (LogLineIndex[])(object)buffer, destinationIndex); } else { var actualIndices = GetOriginalIndices(section); _source.GetColumn(actualIndices, column, buffer, destinationIndex); } }
public void TestInvalidate1() { using (var file = new FilteredLogFile(_taskScheduler, TimeSpan.Zero, _logFile.Object, null, Filter.Create(null, true, LevelFlags.Info))) { _taskScheduler.RunOnce(); file.EndOfSourceReached.Should().BeTrue(); _entries.AddRange(new[] { new LogLine(0, 0, "A", LevelFlags.Info), new LogLine(1, 1, "B", LevelFlags.Info), new LogLine(2, 2, "C", LevelFlags.Info), new LogLine(3, 3, "D", LevelFlags.Info) }); file.OnLogFileModified(_logFile.Object, new LogFileSection(0, 4)); file.OnLogFileModified(_logFile.Object, LogFileSection.Invalidate(2, 2)); _taskScheduler.RunOnce(); file.EndOfSourceReached.Should().BeTrue(); file.Count.Should().Be(2, "because we've invalidated the last 2 out of 4 lines"); } }
/// <inheritdoc /> public override void GetColumn <T>(LogFileSection section, ILogFileColumn <T> column, T[] buffer, int destinationIndex) { if (column == null) { throw new ArgumentNullException(nameof(column)); } if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (destinationIndex < 0) { throw new ArgumentOutOfRangeException(nameof(destinationIndex)); } if (destinationIndex + section.Count > buffer.Length) { throw new ArgumentException("The given buffer must have an equal or greater length than destinationIndex+length"); } if (!TryGetSpecialColumn(section, column, buffer, destinationIndex)) { _source.GetColumn(section, column, buffer, destinationIndex); } }
private LogLineResponse Request(LogFileSection section) { var lines = new LogLine[section.Count]; // TODO: Can we retrieve those lines with fewer locks? for (var i = 0; i < section.Count; ++i) { var index = section.Index + i; LogLine line; if (TryRetrieveFromCache(index, out line)) { lines[i] = line; } else { lines[i] = RetrieveFromAccessor(i); } } return(new LogLineResponse { Lines = lines }); }
private void Clear() { _fullSourceSection = new LogFileSection(); lock (_indices) { _indices.Clear(); } Listeners.OnRead(-1); }
/// <inheritdoc /> public void OnLogFileModified(ILogFile logFile, LogFileSection section) { _pendingModifications.Enqueue(section); ResetEndOfSourceReached(); }
public abstract void GetSection(LogFileSection section, LogLine[] dest);
private void AddRange(ILogFile logFile, LogFileSection section) { LogLine previousLine; if (_lines.Count > 0) previousLine = _lines[_lines.Count - 1]; else previousLine = new LogLine(-1, -1, null, LevelFlags.None); LogLine[] lines = logFile.GetSection(section); for (int i = 0; i < section.Count; ++i) { LogLine line = lines[i]; IncrementCount(line, previousLine); previousLine = line; } _lines.AddRange(lines); }
/// <inheritdoc /> public override void GetColumn <T>(LogFileSection section, ILogFileColumn <T> column, T[] buffer, int destinationIndex) { if (column == null) { throw new ArgumentNullException(nameof(column)); } if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (destinationIndex < 0) { throw new ArgumentOutOfRangeException(nameof(destinationIndex)); } if (destinationIndex + section.Count > buffer.Length) { throw new ArgumentException("The given buffer must have an equal or greater length than destinationIndex+length"); } lock (_syncRoot) { if (Equals(column, LogFileColumns.Index) || Equals(column, LogFileColumns.OriginalIndex)) { GetIndex(section, (LogLineIndex[])(object)buffer, destinationIndex); } else if (Equals(column, LogFileColumns.LogEntryIndex)) { GetIndex(section, (LogEntryIndex[])(object)buffer, destinationIndex); } else if (Equals(column, LogFileColumns.LineNumber) || Equals(column, LogFileColumns.OriginalLineNumber)) { GetLineNumber(section, (int[])(object)buffer, destinationIndex); } else if (Equals(column, LogFileColumns.LogLevel)) { GetLogLevel(section, (LevelFlags[])(object)buffer, destinationIndex); } else if (Equals(column, LogFileColumns.Timestamp)) { GetTimestamp(section, (DateTime?[])(object)buffer, destinationIndex); } else if (Equals(column, LogFileColumns.DeltaTime)) { GetDeltaTime(section, (TimeSpan?[])(object)buffer, destinationIndex); } else if (Equals(column, LogFileColumns.ElapsedTime)) { GetElapsedTime(section, (TimeSpan?[])(object)buffer, destinationIndex); } else if (Equals(column, LogFileColumns.RawContent)) { GetRawContent(section, (string[])(object)buffer, destinationIndex); } else { throw new NoSuchColumnException(column); } } }
public void GetSection(LogFileSection section, LogLine[] dest) { ILogFile logFile = _innerLogFile; if (logFile != null) { logFile.GetSection(section, dest); } else { throw new IndexOutOfRangeException(); } }
/// <summary> /// Retrieves all entries from the given <paramref name="section" /> from this log file and copies /// them into the given <paramref name="buffer" />. /// </summary> /// <param name="logFile"></param> /// <param name="section"></param> /// <param name="buffer"></param> public static void GetEntries(this ILogFile logFile, LogFileSection section, ILogEntries buffer) { GetEntries(logFile, section, buffer, 0); }
public override void GetSection(LogFileSection section, LogLine[] dest) { if (section.Index < 0) throw new ArgumentOutOfRangeException("section.Index"); if (section.Count < 0) throw new ArgumentOutOfRangeException("section.Count"); if (dest == null) throw new ArgumentNullException("dest"); if (dest.Length < section.Count) throw new ArgumentOutOfRangeException("section.Count"); lock (_syncRoot) { if (section.Index + section.Count > _entries.Count) throw new ArgumentOutOfRangeException("section"); _entries.CopyTo((int) section.Index, dest, 0, section.Count); } }
/// <inheritdoc /> protected override TimeSpan RunOnce(CancellationToken token) { var lastCount = _fullSourceSection.Count; bool performedWork = false; LogFileSection section; while (_pendingModifications.TryDequeue(out section) && !token.IsCancellationRequested) { if (section.IsReset) { Clear(); } else if (section.IsInvalidate) { Invalidate(section); } else { _fullSourceSection = LogFileSection.MinimumBoundingLine(_fullSourceSection, section); } performedWork = true; } if (!_fullSourceSection.IsEndOfSection(_currentSourceIndex)) { var remaining = Math.Min(_fullSourceSection.Count - _currentSourceIndex, MaximumBatchSize); var buffer = new LogLine[remaining]; _source.GetSection(new LogFileSection(_currentSourceIndex, remaining), buffer); LogLineIndex?resetIndex = null; lock (_syncRoot) { for (var i = 0; i < remaining; ++i) { var line = buffer[i]; if (_currentLogEntry.EntryIndex.IsInvalid || line.Level != LevelFlags.None || _currentLogEntryLevel == LevelFlags.None) { _currentLogEntry = _currentLogEntry.NextEntry(line.LineIndex); _currentLogEntryLevel = line.Level; } else if (_currentLogEntry.FirstLineIndex < lastCount && resetIndex == null) { var index = _currentLogEntry.FirstLineIndex; resetIndex = index; _currentLogEntryLevel = _source.GetLine((int)index).Level; } _indices.Add(_currentLogEntry); } } if (resetIndex != null) { var resetCount = lastCount - resetIndex.Value; if (resetCount > 0) { Listeners.Invalidate((int)resetIndex.Value, resetCount); } } _currentSourceIndex += remaining; } // Now we can perform a block-copy of all properties. _source.GetValues(_properties); _maxCharactersPerLine = _source.MaxCharactersPerLine; if (_indices.Count != _currentSourceIndex) { Log.ErrorFormat("Inconsistency detected: We have {0} indices for {1} lines", _indices.Count, _currentSourceIndex); } Listeners.OnRead((int)_currentSourceIndex); if (_source.EndOfSourceReached && _fullSourceSection.IsEndOfSection(_currentSourceIndex)) { SetEndOfSourceReached(); } if (performedWork) { return(TimeSpan.Zero); } return(_maximumWaitTime); }
public PendingModification(ILogFile logFile, LogFileSection section) { LogFile = logFile; Section = section; }
public override void GetSection(LogFileSection section, LogLine[] dest) { throw new NotImplementedException(); }
private void Report(int numberOfLinesRead, DateTime now) { // We may never report all lines in one go if the listener specified // that he only wants to receive batches of N. // Therefore we invoke the listener multiple times. int count; while ((count = numberOfLinesRead - _lastNumberOfLines) > 0) { count = Math.Min(count, _maximumCount); var section = new LogFileSection(_lastNumberOfLines, count); _listener.OnLogFileModified(_logFile, section); _lastNumberOfLines += count; _lastReportedTime = now; } }
public void TestGetSection() { using (var proxy = new LogFileProxy(_scheduler, TimeSpan.Zero, _logFile.Object)) { proxy.GetSection(new LogFileSection(42, 101), new LogLine[101]); var expected = new LogFileSection(42, 101); _logFile.Verify(l => l.GetSection(It.Is<LogFileSection>(x => Equals(x, expected)), It.IsAny<LogLine[]>()), Times.Once); } }
internal void OnSizeChanged() { DetermineVerticalOffset(); _currentlyVisibleSection = CalculateVisibleSection(); UpdateVisibleLines(); }
public void UpdateVisibleSection() { _currentlyVisibleSection = CalculateVisibleSection(); }
protected override void OnLogFileModifiedInternal(ILogFile logFile, LogFileSection section) { _modifications.Enqueue(section); }
public void OnLogFileModified(ILogFile logFile, LogFileSection section) { _pendingModifications.Enqueue(section); }
public static LogLine[] GetSection(this ILogFile logFile, LogFileSection section) { var entries = new LogLine[section.Count]; logFile.GetSection(section, entries); return entries; }
private void TextCanvasOnVisibleSectionChanged(LogFileSection section) { CurrentLine = section.Index; }
public void TestToString() { LogFileSection.Reset.ToString().Should().Be("Reset"); LogFileSection.Invalidate(42, 5).ToString().Should().Be("Invalidated [#42, #5]"); }
public void OnLogFileModified(ILogFile logFile, LogFileSection section) { _pendingSections.Enqueue(new KeyValuePair<ILogFile, LogFileSection>(logFile, section)); }
protected override TimeSpan RunOnce(CancellationToken token) { LogFileSection section; while (_pendingModifications.TryDequeue(out section) && !token.IsCancellationRequested) { if (section.IsReset) { Clear(); _lastLogEntry.Clear(); _currentSourceIndex = 0; } else if (section.InvalidateSection) { LogLineIndex startIndex = section.Index; _fullSourceSection = new LogFileSection(0, (int)startIndex); if (_currentSourceIndex > _fullSourceSection.LastIndex) _currentSourceIndex = (int)section.Index; Invalidate(_currentSourceIndex); RemoveInvalidatedLines(_lastLogEntry, _currentSourceIndex); } else { _fullSourceSection = LogFileSection.MinimumBoundingLine(_fullSourceSection, section); } } if (!_fullSourceSection.IsEndOfSection(_currentSourceIndex)) { int remaining = _fullSourceSection.Index + _fullSourceSection.Count - _currentSourceIndex; int nextCount = Math.Min(remaining, BatchSize); var nextSection = new LogFileSection(_currentSourceIndex, nextCount); _source.GetSection(nextSection, _buffer); for (int i = 0; i < nextCount; ++i) { if (token.IsCancellationRequested) break; LogLine line = _buffer[i]; if (_lastLogEntry.Count == 0 || _lastLogEntry[0].LogEntryIndex == line.LogEntryIndex) { _lastLogEntry.Add(line); } else if (line.LogEntryIndex != _lastLogEntry[0].LogEntryIndex) { TryAddLogLine(_lastLogEntry); _lastLogEntry.Clear(); _lastLogEntry.Add(line); } } _currentSourceIndex += nextCount; } if (_fullSourceSection.IsEndOfSection(_currentSourceIndex)) { TryAddLogLine(_lastLogEntry); Listeners.OnRead(_indices.Count); SetEndOfSourceReached(); } return _maximumWaitTime; }
public void OnLogFileModified(ILogFile logFile, LogFileSection section) { if (section.IsReset) { Clear(); } else if (section.InvalidateSection) { RemoveRange(section); } else { AddRange(logFile, section); } }
public void OnLogFileModified(ILogFile logFile, LogFileSection section) { _pendingModifications.Enqueue(section); ResetEndOfSourceReached(); }
private void RemoveRange(LogFileSection section) { LogLine previousLine; if (section.Index > 0) previousLine = _lines[(int) section.Index]; else previousLine = new LogLine(-1, -1, null, LevelFlags.None); for (int i = 0; i < section.Count; ++i) { LogLineIndex index = section.Index + i; LogLine line = _lines[(int) index]; DecrementCount(line, previousLine); previousLine = line; } _lines.RemoveRange((int) section.Index, section.Count); }
/// <inheritdoc /> public override void GetEntries(LogFileSection section, ILogEntries buffer, int destinationIndex) { throw new NotImplementedException(); }
/// <inheritdoc /> public void CopyFrom(ILogFileColumn column, int destinationIndex, ILogFile source, LogFileSection section) { if (column == null) { throw new ArgumentNullException(nameof(column)); } IColumnData columnData; if (!_dataByColumn.TryGetValue(column, out columnData)) { throw new NoSuchColumnException(column); } columnData.CopyFrom(destinationIndex, source, section); }
/// <inheritdoc /> protected override TimeSpan RunOnce(CancellationToken token) { bool performedWork = false; LogFileSection section; while (_pendingModifications.TryDequeue(out section) && !token.IsCancellationRequested) { if (section.IsReset) { Clear(); _lastLogEntry.Clear(); _currentSourceIndex = 0; } else if (section.IsInvalidate) { LogLineIndex startIndex = section.Index; _fullSourceSection = new LogFileSection(0, (int)startIndex); if (_currentSourceIndex > _fullSourceSection.LastIndex) { _currentSourceIndex = (int)section.Index; } Invalidate(_currentSourceIndex); RemoveInvalidatedLines(_lastLogEntry, _currentSourceIndex); } else { _fullSourceSection = LogFileSection.MinimumBoundingLine(_fullSourceSection, section); } performedWork = true; } if (!_fullSourceSection.IsEndOfSection(_currentSourceIndex)) { int remaining = _fullSourceSection.Index + _fullSourceSection.Count - _currentSourceIndex; int nextCount = Math.Min(remaining, BatchSize); var nextSection = new LogFileSection(_currentSourceIndex, nextCount); _source.GetSection(nextSection, _buffer); for (int i = 0; i < nextCount; ++i) { if (token.IsCancellationRequested) { break; } LogLine line = _buffer[i]; if (_lastLogEntry.Count == 0 || _lastLogEntry[0].LogEntryIndex == line.LogEntryIndex) { TryAddLogLine(line); } else if (line.LogEntryIndex != _lastLogEntry[0].LogEntryIndex) { TryAddLogEntry(_lastLogEntry); _lastLogEntry.Clear(); TryAddLogLine(line); } } _currentSourceIndex += nextCount; } if (_fullSourceSection.IsEndOfSection(_currentSourceIndex)) { TryAddLogEntry(_lastLogEntry); Listeners.OnRead(_indices.Count); if (_source.EndOfSourceReached) { SetEndOfSourceReached(); } } if (performedWork) { return(TimeSpan.Zero); } return(_maximumWaitTime); }
public void OnLogFileModified(ILogFile logFile, LogFileSection section) { _pendingModifications.Enqueue(section); }
public void OnLogFileModified(ILogFile logFile, LogFileSection section) { lock (_pendingSections) { if (section == LogFileSection.Reset) _pendingSections.Clear(); _pendingSections.Add(new KeyValuePair<ILogFile, LogFileSection>(_logFile, section)); _dispatcher.BeginInvoke(Synchronize, DispatcherPriority.Background); } }
public void OnLogFileModified(ILogFile logFile, LogFileSection section) { double width = TextHelper.EstimateWidthUpperLimit(logFile.MaxCharactersPerLine); var upperWidth = (int) Math.Ceiling(width); // Setting an integer is an atomic operation and thus no // special synchronization is required. _maxLineWidth = Math.Max(_maxLineWidth, upperWidth); Interlocked.Increment(ref _pendingModificationsCount); }
private void AppendMatches(LogFileSection section) { try { // We've instructed the logfile to give us exactly up to // _logLinesBuffer.Length amount of entries in the ctor, hence the following // is correct: _logFile.GetSection(section, _logLinesBuffer); bool added = false; for (int i = 0; i < section.Count; ++i) { var line = _logLinesBuffer[i]; _filter.Match(line, _matchesBuffer); if (_matchesBuffer.Count > 0) { lock (_syncRoot) { foreach (LogLineMatch logLineMatch in _matchesBuffer) { var match = new LogMatch(line.LineIndex, logLineMatch); _matches.Add(match); } } _matchesBuffer.Clear(); added = true; } } if (added) { _listeners.EmitSearchChanged(_matches); } } catch (IndexOutOfRangeException e) { // This exception is usually thrown when we access a portion of the // log file that has already been reset. This means that a reset event is // either pending or soon to be. So not doing anything else to handle // this exception is fine. Log.DebugFormat("Caught exception while searching log file: {0}", e); } }
private void TextCanvasOnVisibleSectionChanged(LogFileSection section) { CurrentLine = section.Index; }
public override void GetSection(LogFileSection section, LogLine[] dest) { if (section.Index < 0) throw new ArgumentOutOfRangeException("section.Index"); if (section.Count < 0) throw new ArgumentOutOfRangeException("section.Count"); if (dest == null) throw new ArgumentNullException("dest"); if (dest.Length < section.Count) throw new ArgumentOutOfRangeException("section.Count"); lock (_indices) { if (section.Index + section.Count > _indices.Count) throw new ArgumentOutOfRangeException("section"); for (int i = 0; i < section.Count; ++i) { LogLineIndex index = section.Index + i; int sourceIndex = _indices[(int) index]; LogLine line = _source.GetLine(sourceIndex); dest[i] = new LogLine((int)index, line.LogEntryIndex, line.Message, line.Level, line.Timestamp); } } }
/// <inheritdoc /> public override void GetEntries(LogFileSection section, ILogEntries buffer, int destinationIndex) { _source.GetEntries(section, buffer, destinationIndex); }
public Task <LogLineResponse> RequestAsync(LogFileSection section, CancellationToken cancellationToken) { return(_scheduler.StartNew(() => Request(section))); }