コード例 #1
0
            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);
                    }
                }
            }
コード例 #2
0
        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);
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
ファイル: PagedLogBuffer.cs プロジェクト: tank0226/Tailviewer
        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);
        }
コード例 #6
0
ファイル: PagedLogBuffer.cs プロジェクト: tank0226/Tailviewer
        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);
        }
コード例 #7
0
        /// <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);
            }
        }