protected void CopyDataToDestination(LogLineIndex[] sourceIndices, string[] lines, int linesRead) { // We allow users to quickly cancel read requests, for example because their // timeout was reached. When that's the case, then it's possible that we're already // trying to fulfill their request. If we were to still copy the data to the destination // buffer AFTER cancellation then we could get all kinds of weird race conditions and // most of all, break the user's expectation that the buffer must not be modified, // when the GetColumn / GetEntries call has returned! // // Therefore we sync the copy to the destination with the cancellation itself, so that // we can make sure that the above doesn't happen. lock (this) { if (_destination == null) { Log.Debug("Read request cancelled in the mean time, skipping copy to destination buffer"); return; } _destination.CopyFrom(Core.Columns.RawContent, _destinationIndex, lines, 0, linesRead); if (_destination.Contains(Core.Columns.Index)) { _destination.CopyFrom(Core.Columns.Index, _destinationIndex, sourceIndices, 0, linesRead); } } }
public bool TryRead(LogLineIndex sourceStartIndex, int count, ILogBuffer destination, int destinationIndex, bool requiresValidityCheck) { ++_numReads; _lastAccessTime = DateTime.UtcNow; var pageSourceIndex = sourceStartIndex - _section.Index; var range = new Int32Range(pageSourceIndex, count); foreach (var column in _buffer.Columns) { if (destination.Contains(column)) { destination.CopyFrom(column, destinationIndex, _buffer, range); } } if (requiresValidityCheck) { if (_buffer.ContainsAnyDefault(Columns.Index, range)) { return(false); } } return(true); }
/// <summary> /// Returns a new log buffer which acts as a view onto the original buffer. /// If the original buffer ONLY contains the desired column, then the original buffer is returned. /// Otherwise a new temporary buffer is returned with the same size as the original buffer containing /// only the given column. /// </summary> /// <param name="that"></param> /// <param name="column"></param> /// <returns></returns> public static ILogBuffer CreateViewOnlyWithColumn(this ILogBuffer that, IColumnDescriptor column) { if (that.Columns.Count == 1 && that.Contains(column)) { return(that); } var temporaryBuffer = new LogBufferArray(that.Count, column); return(temporaryBuffer); }
private static IReadOnlyList <IColumnDescriptor> FindAugmentedColumns(ILogBuffer destination) { var augmented = new List <IColumnDescriptor>(MaxAdornedColumns.Count); foreach (var column in MaxAdornedColumns) { if (destination.Contains(column)) { augmented.Add(column); } } return(augmented); }
private bool TryGetEntriesContiguous(LogSourceSection sourceSection, ILogBuffer destination, int destinationIndex, out IReadOnlyList <LogSourceSection> accessedPageBoundaries) { bool fullyRead = true; var sourceSectionEndIndex = Math.Min((int)(sourceSection.Index + sourceSection.Count), _sourceCount); var numEntriesRead = 0; var tmpAccessedPageBoundaries = new List <LogSourceSection>(); for (LogLineIndex i = sourceSection.Index; i < sourceSectionEndIndex;) { var pageIndex = GetPageIndex(i); var remainingPageCount = (pageIndex + 1) * _pageSize - i; var count = Math.Min(remainingPageCount, sourceSectionEndIndex - i); var page = TryGetPage(pageIndex); if (page != null) { fullyRead &= page.TryRead(i, count, destination, destinationIndex + numEntriesRead, fullyRead); tmpAccessedPageBoundaries.Add(page.Section); } else { destination.FillDefault(destinationIndex + numEntriesRead, count); if (destination.Contains(PageBufferedLogSource.RetrievalState)) { destination.Fill(PageBufferedLogSource.RetrievalState, RetrievalState.NotCached, destinationIndex + numEntriesRead, count); } fullyRead = false; tmpAccessedPageBoundaries.Add(GetSectionForPage(pageIndex)); } numEntriesRead += count; i += count; } if (numEntriesRead < sourceSection.Count) { var start = destinationIndex + numEntriesRead; destination.FillDefault(start, sourceSection.Count - numEntriesRead); fullyRead = false; } accessedPageBoundaries = tmpAccessedPageBoundaries; return(fullyRead); }
private bool TryGetEntriesSegmented(IReadOnlyList <LogLineIndex> sourceIndices, ILogBuffer destination, int destinationStartIndex, out IReadOnlyList <LogSourceSection> accessedPageBoundaries) { var tmpAccessedPageBoundaries = new List <LogSourceSection>(); bool fullyRead = true; for (int i = 0; i < sourceIndices.Count; ++i) { var sourceIndex = sourceIndices[i]; var destinationIndex = destinationStartIndex + i; if (sourceIndex.IsValid) { var pageIndex = GetPageIndex(sourceIndex); var page = TryGetPage(pageIndex); if (page != null) { fullyRead &= page.TryRead(sourceIndex, 1, destination, destinationIndex, fullyRead); tmpAccessedPageBoundaries.Add(page.Section); } else { destination.FillDefault(destinationIndex, 1); if (destination.Contains(PageBufferedLogSource.RetrievalState)) { var state = sourceIndex >= _sourceCount ? RetrievalState.NotInSource : RetrievalState.NotCached; destination.Fill(PageBufferedLogSource.RetrievalState, state, destinationIndex, 1); } fullyRead = false; tmpAccessedPageBoundaries.Add(GetSectionForPage(pageIndex)); } } else { destination.FillDefault(destinationIndex, 1); } } accessedPageBoundaries = tmpAccessedPageBoundaries; return(fullyRead); }
/// <inheritdoc /> public void GetEntries(IReadOnlyList <LogLineIndex> sourceIndices, ILogBuffer destination, int destinationIndex, LogSourceQueryOptions queryOptions) { var source = _source; if (source != null) { var columnsToCopy = new IColumnDescriptor[] { Core.Columns.Index, Core.Columns.RawContent }; var tmp = new LogBufferArray(sourceIndices.Count, columnsToCopy); source.GetEntries(sourceIndices, tmp, 0, queryOptions); foreach (var column in columnsToCopy) { if (destination.Contains(column)) { destination.CopyFrom(column, destinationIndex, tmp, new Int32Range(0, sourceIndices.Count)); } } for (var i = 0; i < sourceIndices.Count; ++i) { var parsedLogEntry = _parser.Parse(tmp[i]); if (parsedLogEntry != null) { destination[destinationIndex + i].CopyFrom(parsedLogEntry); } else { destination[destinationIndex + i].CopyFrom(_nothingParsed); } } } else { destination.FillDefault(destinationIndex, sourceIndices.Count); } }