Example #1
0
        private RelativeIndex CalculateRelativeIndex(int index, ref IndexCollection indexCollection,
                                                     LastValueWrapper lastValueWrapper)
        {
            var firstLineInContainer = 0;
            var lastLineInContainer  = 0;

            while (indexCollection != null)
            {
                foreach (var sparseIndex in indexCollection.Indicies)
                {
                    lastLineInContainer += sparseIndex.LineCount;
                    if (index < lastLineInContainer)
                    {
                        //It could be that the user is scrolling into a part of the file
                        //which is still being indexed [or will never be indexed].
                        //In this case we need to estimate where to scroll to
                        if (sparseIndex.LineCount != 0 && sparseIndex.Indicies.Count == 0)
                        {
                            //return estimate here!
                            var lines        = sparseIndex.LineCount;
                            var bytes        = sparseIndex.End - sparseIndex.Start;
                            var bytesPerLine = bytes / lines;
                            var estimate     = index * bytesPerLine;


                            return(new RelativeIndex(index, estimate, 0, true));
                        }

                        var relativePosition = (index - firstLineInContainer);
                        var relativeIndex    = relativePosition / sparseIndex.Compression;
                        var offset           = relativePosition % sparseIndex.Compression;

                        if (relativeIndex >= sparseIndex.IndexCount)
                        {
                            relativeIndex = sparseIndex.IndexCount - 1;
                        }
                        var start = relativeIndex == 0 ? 0 : sparseIndex.Indicies[relativeIndex - 1];
                        return(new RelativeIndex(index, start, offset, false));
                    }
                    firstLineInContainer = firstLineInContainer + sparseIndex.LineCount;
                }
                lastValueWrapper.LastEndPosition += indexCollection.Indicies
                                                    .Where(localIndex => localIndex.IndexCount > 0)
                                                    .Sum(localIndex => localIndex.Indicies[localIndex.IndexCount - 1]);

                indexCollection = indexCollection.Previous as IndexCollection;
            }

            return(null);
        }
        public IEnumerable <Line> ReadLines(ScrollRequest scroll)
        {
            var current          = ReverseLinking(this);
            var page             = GetPage(scroll, this);
            var lastValueWrapper = new LastValueWrapper();

            if (page.Size == 0)
            {
                yield break;
            }
            while (current != null)
            {
                using (
                    var stream = File.Open(current.Info.FullName, FileMode.Open, FileAccess.Read,
                                           FileShare.Delete | FileShare.ReadWrite))
                {
                    using (var reader = new StreamReaderExtended(stream, current.Encoding, false))
                    {
                        if (page.Size == 0)
                        {
                            yield break;
                        }

                        if (lastValueWrapper.LastPageIndex == page.Start + page.Size)
                        {
                            yield break;
                        }
                        var  counter    = 0;
                        long lastEndPos = 0;
                        foreach (
                            var i in
                            Enumerable.Range(
                                lastValueWrapper.LastPageIndex > 0 ? lastValueWrapper.LastPageIndex : page.Start,
                                page.Size - counter))
                        {
                            if (i == page.Start + page.Size)
                            {
                                yield break;
                            }
                            if (i - lastValueWrapper.LastMatchesSize > current.Count - 1)
                            {
                                lastValueWrapper.LastEndPosition += lastEndPos + 1;
                                lastValueWrapper.LastMatchesSize += current.Count;
                                break;
                            }

                            var start         = current.Matches[i - lastValueWrapper.LastMatchesSize];
                            var startPosition = reader.AbsolutePosition();

                            if (startPosition != start)
                            {
                                reader.DiscardBufferedData();
                                reader.BaseStream.Seek(start, SeekOrigin.Begin);
                            }

                            startPosition = reader.AbsolutePosition();

                            var line        = reader.ReadLine();
                            var endPosition = reader.AbsolutePosition();
                            var info        = new LineInfo(i + 1, i, startPosition + lastValueWrapper.LastEndPosition,
                                                           endPosition + lastValueWrapper.LastEndPosition);

                            var ontail = endPosition >= TailInfo.TailStartsAt &&
                                         DateTime.Now.Subtract(TailInfo.LastTail).TotalSeconds < 1
                                ? DateTime.Now
                                : (DateTime?)null;

                            yield return(new Line(info, line, ontail));

                            lastValueWrapper.LastPageIndex = i + 1;
                            counter++;
                            lastEndPos = endPosition;

                            if (reader.EndOfStream)
                            {
                                lastValueWrapper.LastEndPosition += endPosition + 1;
                                lastValueWrapper.LastMatchesSize += current.Count;
                                break;
                            }
                        }
                    }
                }
                current = current.Next as FileSearchResult;
            }
        }
Example #3
0
        private IEnumerable <Line> ReadLinesByIndex(ScrollRequest scroll)
        {
            var current          = this;
            var lastValueWrapper = new LastValueWrapper();
            var iterationCounter = 0;
            var page             = GetPage(scroll, current);
            var relativeIndex    = CalculateRelativeIndex(page.Start, ref current, lastValueWrapper);

            while (relativeIndex != null && current != null)
            {
                if (current.Indicies.Length > 0 && current.Indicies.Any(t => t.Indicies.Count == 0))
                {
                    iterationCounter++;
                    current = current.Previous as IndexCollection;
                    continue;
                }
                if (lastValueWrapper.LastPageIndex == page.Start + page.Size)
                {
                    yield break;
                }
                var offset = relativeIndex.LinesOffset;
                using (
                    var stream = File.Open(current.Info.FullName, FileMode.Open, FileAccess.Read,
                                           FileShare.Delete | FileShare.ReadWrite))
                {
                    using (var reader = new StreamReaderExtended(stream, current.Encoding, false))
                    {
                        //go to starting point
                        stream.Seek((iterationCounter > 0) ? 0 : relativeIndex.Start, SeekOrigin.Begin);
                        if (iterationCounter == 0 && offset > 0)
                        {
                            //skip number of lines offset
                            for (var i = 0; i < offset; i++)
                            {
                                reader.ReadLine();
                            }
                        }

                        //if estimate move to the next start of line
                        if (iterationCounter == 0 && relativeIndex.IsEstimate && relativeIndex.Start != 0)
                        {
                            reader.ReadLine();
                        }

                        foreach (
                            var i in
                            Enumerable.Range((iterationCounter > 0) ? lastValueWrapper.LastPageIndex : page.Start,
                                             page.Size))
                        {
                            if (i == page.Start + page.Size)
                            {
                                yield break;
                            }
                            var startPosition = reader.AbsolutePosition() + lastValueWrapper.LastEndPosition;
                            var line          = reader.ReadLine();
                            var endPosition   = reader.AbsolutePosition() + lastValueWrapper.LastEndPosition;

                            var info = new LineInfo(i + 1, i, startPosition, endPosition);

                            var ontail = startPosition >= current.TailInfo.TailStartsAt &&
                                         DateTime.Now.Subtract(current.TailInfo.LastTail).TotalSeconds < 1
                                ? DateTime.Now
                                : (DateTime?)null;

                            yield return(new Line(info, line, ontail));

                            lastValueWrapper.LastPageIndex = i + 1;

                            if (reader.EndOfStream)
                            {
                                lastValueWrapper.LastEndPosition += endPosition + 1;
                                break;
                            }
                        }
                    }
                }
                iterationCounter++;
                current = current.Previous as IndexCollection;
            }
        }