protected override void OnSectionAppended(LogSourceSection section, IReadOnlyLogBuffer data, int totalLogEntryCount) { lock (_syncRoot) { _buffer.AddRange(data, section.Count); } }
/// <summary> /// Adds data from the given source to this cache. /// </summary> /// <param name="destinationSection">The destination indices of the log entries from the given source</param> /// <param name="source">The source from which to copy data to this buffer</param> /// <param name="sourceIndex">The index into the given source from which onwards log entries may be added to this cache.</param> public void TryAdd(LogSourceSection destinationSection, IReadOnlyLogBuffer source, int sourceIndex) { if (!CanCache(source)) { return; } // We want to make sure to only read that data, which is actually covered by the log source. // This is because one thread might resize this buffer to a smaller size and then another thread // might try to add data which has been previously read, but is now no longer supposed to be part of the source. var sourceSectionEndIndex = Math.Min((int)(destinationSection.Index + destinationSection.Count), _sourceCount); for (LogLineIndex i = destinationSection.Index; i < sourceSectionEndIndex;) { var pageIndex = GetPageIndex(i); var page = GetOrCreatePageByIndex(pageIndex); var remainingPageCount = (pageIndex + 1) * _pageSize - i; var count = Math.Min(remainingPageCount, sourceSectionEndIndex - i); var sourceStartIndex = (i - destinationSection.Index) + sourceIndex; page.Add(sourceStartIndex, count, source, i); // We want the next copy operation to start at the beginning of the next page (it's a contiguous write after all) i += remainingPageCount; } }
private IEnumerable <MergedLogLineIndex> CreateIndices(IReadOnlyLogBuffer buffer, byte logFileIndex) { // DO NOT CALL EXTERNAL / VIRTUAL METHODS OF ANY KIND HERE if (buffer == null) { return(Enumerable.Empty <MergedLogLineIndex>()); } var indices = new List <MergedLogLineIndex>(); foreach (var entry in buffer) { var index = entry.GetValue(Columns.Index); var entryIndex = entry.GetValue(Columns.LogEntryIndex); var timestamp = entry.GetValue(Columns.Timestamp); if (index.IsValid && entryIndex.IsValid && //< Invalid values are possible if the file has been invalidated in between it sending us a change and us having retrieved the corresponding data timestamp != null) //< Not every line has a timestamp { indices.Add(new MergedLogLineIndex(index.Value, -1, //< We don't know the LogEntryIndex until insertion, hence we use a place-holder value here entryIndex.Value, logFileIndex, timestamp.Value)); } } return(indices); }
protected override ILogSource CreateFromContent(IReadOnlyLogBuffer content) { var fileName = PathEx.GetTempFileName(); TestContext.Progress.WriteLine("File: {0}", fileName); using (var stream = File.OpenWrite(fileName)) using (var writer = new StreamWriter(stream)) { for (int i = 0; i < content.Count; ++i) { var logEntry = content[i]; if (logEntry.TryGetValue(Columns.Timestamp, out var timestamp) && timestamp != null) { // Let's write the timestamp in a format everybody recognizes writer.Write("{0:yyyy-MM-dd HH:mm:ss.fffffff}", timestamp); } writer.Write(logEntry.ToString()); if (i < content.Count - 1) { writer.WriteLine(); } } } var fileLogSource = new FileLogSource(_services, fileName); fileLogSource.Property(x => x.GetProperty(Properties.PercentageProcessed)).ShouldEventually().Be(Percentage.HundredPercent); return(fileLogSource); }
protected override ILogSource CreateFromContent(IReadOnlyLogBuffer content) { var source = new InMemoryLogSource(content); var proxy = new LogSourceProxy(_taskScheduler, TimeSpan.Zero, source); _taskScheduler.RunOnce(); return(proxy); }
/// <inheritdoc /> public void CopyFrom(IColumnDescriptor column, int destinationIndex, IReadOnlyLogBuffer source, IReadOnlyList <int> sourceIndices) { if (!_sourceBufferByColumn.TryGetValue(column, out var sourceBuffer)) { throw new NoSuchColumnException(column); } sourceBuffer.CopyFrom(column, destinationIndex, source, sourceIndices); }
/// <summary> /// /// </summary> /// <param name="source"></param> /// <param name="count"></param> public void AddRange(IReadOnlyLogBuffer source, int count) { var start = _count; Resize(_count + count); foreach (var column in _dataByColumn.Values) { column.CopyFrom(start, source, new Int32Range(0, count)); } }
/// <inheritdoc /> public void CopyFrom(IColumnDescriptor column, int destinationIndex, IReadOnlyLogBuffer source, IReadOnlyList <int> sourceIndices) { if (!_columns.Contains(column)) { throw new NoSuchColumnException(column); } _inner.CopyFrom(column, destinationIndex, source, sourceIndices); }
public void Add(int sourceIndex, int count, IReadOnlyLogBuffer source, LogLineIndex destinationIndex) { // Let us see where that data lies in this page.. var pageDestinationIndex = destinationIndex - _section.Index; foreach (var column in _copiedColumns) { _buffer.CopyFrom(column, pageDestinationIndex, source, new Int32Range(sourceIndex, count)); } // We neither need, nor want the source buffer to have to supply the indices - we know them ourselves _buffer.CopyFrom(Columns.Index, pageDestinationIndex, new LogSourceSection(_section.Index + pageDestinationIndex, count), 0, count); _buffer.Fill(PageBufferedLogSource.RetrievalState, RetrievalState.Retrieved, pageDestinationIndex, count); }
private bool CanCache(IReadOnlyLogBuffer source) { var sourceColumns = source.Columns; foreach (var cachedColumn in _requiredColumns) { if (!sourceColumns.Contains(cachedColumn)) { return(false); } } return(true); }
/// <inheritdoc /> public void CopyFrom(IColumnDescriptor column, int destinationIndex, IReadOnlyLogBuffer source, IReadOnlyList <int> sourceIndices) { if (column == null) { throw new ArgumentNullException(nameof(column)); } if (!_dataByColumn.TryGetValue(column, out var columnData)) { throw new NoSuchColumnException(column); } columnData.CopyFrom(destinationIndex, source, sourceIndices); }
/// <inheritdoc /> public void CopyFrom(IColumnDescriptor column, int destinationIndex, IReadOnlyLogBuffer source, IReadOnlyList <int> sourceIndices) { if (column == null) { throw new ArgumentNullException(nameof(column)); } if (!Equals(column, _column)) { throw new NoSuchColumnException(column); } // This view may be constructed with a specific offset into the _buffer and therefore, when // instructing the other buffer to copy its data into ours, we have to take into account // both the internal offset as well as the destination index into the visible portion of this // buffer upon construction. source.CopyTo(_column, sourceIndices, _buffer, _offset + destinationIndex); }
public MergedLogSourceSection(ILogSource logSource, LogSourceModification modification, IReadOnlyLogBuffer buffer) { LogSource = logSource; Modification = modification; Buffer = buffer; }
protected override ILogSource CreateFromContent(IReadOnlyLogBuffer content) { var source = new InMemoryLogSource(content); return(new PageBufferedLogSource(_taskScheduler, source, TimeSpan.Zero)); }
public void CopyFrom(int destinationIndex, IReadOnlyLogBuffer source, IReadOnlyList <int> sourceIndices) { source.CopyTo(_column, sourceIndices, _data, destinationIndex); }
/// <summary> /// /// </summary> /// <param name="section"></param> /// <param name="data"></param> /// <param name="totalLogEntryCount"></param> protected abstract void OnSectionAppended(LogSourceSection section, IReadOnlyLogBuffer data, int totalLogEntryCount);
protected override ILogSource CreateFromContent(IReadOnlyLogBuffer content) { var source = new InMemoryLogSource(content); return(new NoThrowLogSource(source, "")); }
public MergedLogSourceSection(ILogSource logSource, LogSourceModification modification) { LogSource = logSource; Modification = modification; Buffer = null; }
protected override ILogSource CreateFromContent(IReadOnlyLogBuffer content) { var logFile = new InMemoryLogSource(content); return(logFile); }
public ReadOnlyLogBufferEnumerator(IReadOnlyLogBuffer logBuffer) { _logBuffer = logBuffer; Reset(); }
/// <summary> /// Initializes this object. /// </summary> /// <param name="content"></param> public InMemoryLogSource(IReadOnlyLogBuffer content) : this(content.Columns) { AddRange(content); }