예제 #1
0
        async Task <bool> IScreenBuffer.MoveToBookmark(
            IBookmark bookmark,
            BookmarkLookupMode mode,
            CancellationToken cancellation)
        {
            var matchMode = mode & BookmarkLookupMode.MatchModeMask;
            Func <DisplayLine, int> cmp = (DisplayLine l) =>
            {
                var ret = MessagesComparer.CompareLogSourceConnectionIds(l.Message.GetConnectionId(), bookmark.LogSourceConnectionId);
                if (ret == 0)
                {
                    ret = Math.Sign(l.Message.Position - bookmark.Position);
                }
                if (ret == 0)
                {
                    ret = Math.Sign(l.LineIndex - bookmark.LineIndex);
                }
                return(ret);
            };

            return(await PerformBuffersTransaction(
                       string.Format("MoveToBookmark({0})", mode),
                       cancellation,
                       modifyBuffers : tmp => Task.WhenAll(tmp.Select(buf =>
                                                                      matchMode == BookmarkLookupMode.ExactMatch && buf.Source.LogSourceHint?.ConnectionId == bookmark.LogSourceConnectionId ?
                                                                      buf.LoadAround(bookmark.Position, GetMaxBufferSize(viewSize) + bookmark.LineIndex, cancellation) :
                                                                      buf.LoadAt(bookmark.Time.ToLocalDateTime(), GetMaxBufferSize(viewSize) + bookmark.LineIndex, cancellation)
                                                                      )),
                       getPivotLine : (lines, bufs) =>
            {
                DisplayLine ret = new DisplayLine();
                if (matchMode == BookmarkLookupMode.ExactMatch)
                {
                    ret = lines.FirstOrDefault(l => cmp(l) == 0);
                }
                else if (matchMode == BookmarkLookupMode.FindNearestMessage)
                {
                    ret = lines.FirstOrDefault(l => cmp(l) >= 0);
                    if (ret.IsEmpty)
                    {
                        ret = lines.LastOrDefault(l => cmp(l) < 0);
                    }
                }
                return ret.Message == null ? null : Tuple.Create(ret, ComputeMatchedLinePosition(mode));
            }
                       ) != null);
        }
예제 #2
0
 double ComputeMatchedLinePosition(BookmarkLookupMode mode)
 {
     return((mode & BookmarkLookupMode.MoveBookmarkToMiddleOfScreen) != 0 ? Math.Max(viewSize - 1d, 0) / 2d : 0d);
 }
예제 #3
0
        async Task <bool> IScreenBuffer.MoveToBookmark(
            IBookmark bookmark,
            BookmarkLookupMode mode,
            CancellationToken cancellation)
        {
            using (CreateTrackerForNewOperation(string.Format("MoveToBookmark({0})", mode), cancellation))
            {
                var matchMode                = mode & BookmarkLookupMode.MatchModeMask;
                MessageTimestamp dt          = bookmark.Time;
                long             position    = bookmark.Position;
                int    lineIndex             = bookmark.LineIndex;
                string logSourceCollectionId = bookmark.LogSourceConnectionId;
                var    tmp   = buffers.ToDictionary(s => s.Key, s => new SourceBuffer(s.Value));
                var    tasks = tmp.Select(s => new
                {
                    buf  = s.Value,
                    task =
                        (buffers.Count == 1 && matchMode == BookmarkLookupMode.ExactMatch) ?
                        GetScreenBufferLines(s.Key, position, bufferSize, EnumMessagesFlag.Forward | EnumMessagesFlag.IsActiveLogPositionHint, isRawLogMode, cancellation) :
                        GetScreenBufferLines(s.Key, dt.ToLocalDateTime(), bufferSize, isRawLogMode, cancellation),
                }).ToList();
                await Task.WhenAll(tasks.Select(i => i.task));

                cancellation.ThrowIfCancellationRequested();
                foreach (var t in tasks)
                {
                    t.buf.Set(t.task.Result);
                }
                bool messageFound = false;
                if (matchMode == BookmarkLookupMode.FindNearestTime)
                {
                    messageFound = true;
                }
                else
                {
                    foreach (var i in GetMessagesInternal(tmp.Values).Forward(0, int.MaxValue))
                    {
                        var cmp = MessagesComparer.CompareLogSourceConnectionIds(i.Message.Message.GetConnectionId(), logSourceCollectionId);
                        if (cmp == 0)
                        {
                            cmp = Math.Sign(i.Message.Message.Position - position);
                        }
                        if (cmp == 0)
                        {
                            cmp = Math.Sign(((SourceBuffer)i.SourceCollection).Get(i.SourceIndex).LineIndex - lineIndex);
                        }
                        if (matchMode == BookmarkLookupMode.ExactMatch)
                        {
                            messageFound = cmp == 0;
                        }
                        else if (matchMode == BookmarkLookupMode.FindNearestBookmark)
                        {
                            messageFound = cmp > 0;
                        }
                        if (messageFound)
                        {
                            break;
                        }
                        var sb = ((SourceBuffer)i.SourceCollection);
                        sb.UnnededTopMessages++;
                    }
                }
                if (!messageFound)
                {
                    if (matchMode == BookmarkLookupMode.FindNearestBookmark)
                    {
                        await MoveToStreamsEndInternal(cancellation);

                        return(true);
                    }
                    return(false);
                }

                buffers = tmp;

                FinalizeSourceBuffers();

                if (AllLogsAreAtEnd())
                {
                    await MoveToStreamsEndInternal(cancellation);
                }
                else
                {
                    SetScrolledLines(0);
                    if ((mode & BookmarkLookupMode.MoveBookmarkToMiddleOfScreen) != 0)
                    {
                        var additionalSpace = ((int)Math.Floor(viewSize) - 1) / 2;
                        if (additionalSpace > 0)
                        {
                            await ShiftByInternal(-additionalSpace, cancellation);
                        }
                    }
                }

                return(true);
            }
        }