private void AddLines(FixedSizeList <long> buffer, Percentage percentageProcessed, long lastLineOffsetStreamPosition) { int?lineIndexToInvalidate = null; int count; lock (_index) { if (_index.Count > 0) { var lastLineIndex = _index.Count - 1; if (_index[lastLineIndex].GetValue(LineOffsetInBytes) == lastLineOffsetStreamPosition) { lineIndexToInvalidate = lastLineIndex; } } if (buffer.Count > 0) { //if (buffer.Buffer[0] != lastLineOffsetStreamPosition) //{ // var lastLineIndex = _index.Count - 1; // lineIndexToInvalidate = lastLineIndex; //} for (int i = 0; i < buffer.Count; ++i) { _index.Add(CreateLogEntry(buffer.Buffer[i])); } _lastLineOffsetStreamPosition = buffer.Buffer[buffer.Count - 1]; buffer.Clear(); } count = _index.Count; } if (lineIndexToInvalidate != null) { _listeners.Remove(lineIndexToInvalidate.Value, 1); } _propertiesBuffer.SetValue(Core.Properties.PercentageProcessed, percentageProcessed); UpdateLineCount(count); }
private bool ReadEntireFile(CancellationToken cancellationToken) { if (!HasFileChanged(out var currentFingerprint, out var previousFingerprint)) { if (Log.IsDebugEnabled) { Log.DebugFormat("File {0} remains unchanged (Fingerprint: {1}), nothing to do...", _fileName, currentFingerprint); } return(false); } var start = DateTime.UtcNow; if (Log.IsDebugEnabled) { Log.DebugFormat("File {0} change detected (Fingerprint: {1}), scanning for new lines...", _fileName, currentFingerprint); } if (previousFingerprint?.Size > currentFingerprint.Size) { if (Log.IsDebugEnabled) { Log.DebugFormat("File {0} size reduced from {1}bytes to {2} bytes, starting all over", _fileName, previousFingerprint.Size, currentFingerprint.Size); } Clear(); } using (var stream = new FileStream(_fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) { _propertiesBuffer.SetValue(Core.Properties.EmptyReason, null); var startOffset = _lastLineOffsetStreamPosition; if (startOffset == 0) { AddFirstLineIfNecessary(stream); } else { stream.Position = startOffset; } var detector = new LineOffsetDetector(stream, _encoding); var buffer = new FixedSizeList <long>(1000); long lineOffset; while ((lineOffset = detector.FindNextLineOffset()) >= 0) { if (cancellationToken.IsCancellationRequested) { return(false); } if (!buffer.TryAdd(lineOffset)) { AddLines(buffer, Percentage.Of(stream.Position, currentFingerprint.Size), startOffset); buffer.TryAdd(lineOffset); } } AddLines(buffer, Percentage.HundredPercent, startOffset); _lastStreamPosition = stream.Position; } if (Log.IsDebugEnabled) { var elapsed = DateTime.UtcNow - start; Log.DebugFormat("File {0} scan finished, took: {1:F1}ms", _fileName, elapsed.TotalMilliseconds); } return(true); }