Beispiel #1
0
        private IReadOnlyList <LogSourceModification> Process(IReadOnlyList <MergedLogSourceSection> pendingModifications)
        {
            // This method keeps track of the changes made
            // to the index structure in this object and then returns
            // the list once it is done.
            // It will try to compress the changes to the bare minimum
            // (which it can do if given more pending modifications at once).

            lock (_syncRoot)
            {
                var stopwatch = Stopwatch.StartNew();

                var changes = new MergedLogSourceChanges(_indices.Count);

                ProcessResetsNoLock(pendingModifications, changes);

                ProcessInvalidationsNoLock(pendingModifications, changes);

                ProcessAppendsNoLock(pendingModifications, changes);

                UpdateLogEntryIndicesNoLock(changes);

                stopwatch.Stop();
                if (Log.IsDebugEnabled)
                {
                    int lineCount = pendingModifications.Sum(x => x.Modification.IsAppended(out var appendedSection) ? appendedSection.Count : 0);
                    Log.DebugFormat("MergedLogFileIndex::Process(#{0} modifications, #{1} lines): {2}ms", pendingModifications.Count, lineCount, stopwatch.ElapsedMilliseconds);
                }

                return(changes.Sections);
            }
        }
Beispiel #2
0
        private void UpdateLogEntryIndicesNoLock(MergedLogSourceChanges changes)
        {
            // DO NOT CALL EXTERNAL / VIRTUAL METHODS OF ANY KIND HERE

            // We only need to re-calculate those indices if there was an invalidation or a portion
            // of this index. If there wasn't, then ProcessAppendsNoLock() already does its job as required...
            if (changes.TryGetFirstRemovedIndex(out var firstRemovedIndex))
            {
                for (int i = firstRemovedIndex.Value; i < _indices.Count; ++i)
                {
                    var index = _indices[i];
                    index.MergedLogEntryIndex = (int)CalculateLogEntryIndexFor(i, index);
                    _indices[i] = index;
                }
            }
        }
Beispiel #3
0
        private void ProcessAppendsNoLock(IReadOnlyList <MergedLogSourceSection> pendingModifications, MergedLogSourceChanges changes)
        {
            // DO NOT CALL EXTERNAL / VIRTUAL METHODS OF ANY KIND HERE

            var indices = CreateIndices(pendingModifications);

            var removed             = false;
            var appendStartingIndex = _indices.Count;

            foreach (var index in indices)
            {
                var insertionIndex = FindInsertionIndexNoLock(index);
                if (insertionIndex < _indices.Count)
                {
                    if (!removed)
                    {
                        // Here's the awesome thing: We're inserting a "pre-sorted" list of indices
                        // into our index buffer. Therefore, the very first index which requires an invalidation
                        // is also the LOWEST POSSIBLE index which could require an invalidation and therefore
                        // there can only ever be one invalidation while this method is executing.

                        // We do need to take into account that even though we're invalidating a region,
                        // that doesn't mean we also didn't append something previously....
                        var appendCount = _indices.Count - appendStartingIndex;
                        if (appendCount > 0)
                        {
                            changes.Append(appendStartingIndex, appendCount);
                        }

                        changes.RemoveFrom(insertionIndex);
                        removed = true;
                    }
                }

                var actualIndex = index;
                actualIndex.MergedLogEntryIndex = (int)CalculateLogEntryIndexFor(insertionIndex, index);
                _indices.Insert(insertionIndex, actualIndex);
            }

            var appendCount2 = _indices.Count - appendStartingIndex;

            if (appendCount2 > 0)
            {
                changes.Append(appendStartingIndex, appendCount2);
            }
        }
Beispiel #4
0
        private void ProcessInvalidationsNoLock(IReadOnlyList <MergedLogSourceSection> pendingModifications, MergedLogSourceChanges changes)
        {
            // DO NOT CALL EXTERNAL / VIRTUAL METHODS OF ANY KIND HERE

            foreach (var pendingModification in pendingModifications)
            {
                if (pendingModification.Modification.IsRemoved(out var removedSection))
                {
                    var logFileIndex = GetLogFileIndex(pendingModification.LogSource);
                    bool Predicate(MergedLogLineIndex x) => x.SourceId == logFileIndex && x.SourceLineIndex >= removedSection.Index;

                    var firstIndex = _indices.FindIndex(Predicate);
                    if (firstIndex >= 0)
                    {
                        _indices.RemoveAll(Predicate);
                        if (_indices.Count == 0)
                        {
                            changes.Reset();
                        }
                        else
                        {
                            changes.RemoveFrom(firstIndex);

                            var appendCount = _indices.Count - firstIndex;
                            if (appendCount > 0)
                            {
                                changes.Append(firstIndex, appendCount);
                            }
                        }
                    }
                }
            }
        }