Пример #1
0
 public Message(
     long position,
     long endPosition,
     IThread t,
     MessageTimestamp time,
     StringSlice text,
     SeverityFlag s,
     StringSlice rawText = new StringSlice(),
     int?maxLineLen      = null
     )
 {
     if (endPosition < position)
     {
         throw new ArgumentException("bad message positions");
     }
     this.thread      = t;
     this.time        = time;
     this.position    = position;
     this.endPosition = endPosition;
     this.text        = text;
     this.rawText     = rawText;
     this.flags       = (MessageFlag)s;
     if (maxLineLen != null)
     {
         this.rawText = this.rawText.Wrap(maxLineLen.Value);
         this.text    = this.text.Wrap(maxLineLen.Value);
     }
 }
Пример #2
0
 void LoadBookmarks()
 {
     using (new ScopedGuard(() => loadingLogSourceInfoFromStorageEntry = true, () => loadingLogSourceInfoFromStorageEntry = false))
         using (var section = logSourceSpecificStorageEntry.OpenXMLSection("bookmarks", Persistence.StorageSectionOpenFlag.ReadOnly))
         {
             var root = section.Data.Element("bookmarks");
             if (root == null)
             {
                 return;
             }
             foreach (var elt in root.Elements("bookmark"))
             {
                 var time      = elt.Attribute("time");
                 var thread    = elt.Attribute("thread-id");
                 var name      = elt.Attribute("display-name");
                 var position  = elt.Attribute("position");
                 var lineIndex = elt.Attribute("line-index");
                 if (time != null && thread != null && name != null && position != null)
                 {
                     bookmarks.ToggleBookmark(bookmarks.Factory.CreateBookmark(
                                                  MessageTimestamp.ParseFromLoselessFormat(time.Value),
                                                  logSourceThreads.GetThread(new StringSlice(thread.Value)),
                                                  name.Value,
                                                  long.Parse(position.Value),
                                                  (lineIndex != null) ? int.Parse(lineIndex.Value) : 0
                                                  ));
                 }
             }
         }
 }
Пример #3
0
 internal Bookmark(MessageTimestamp time, IThread thread, string logSourceConnectionId,
                   string displayName, long position, int lineIndex)
 {
     this.time                  = time;
     this.thread                = thread;
     this.displayName           = displayName;
     this.position              = position;
     this.logSourceConnectionId = logSourceConnectionId;
     this.lineIndex             = lineIndex;
 }
Пример #4
0
        public static async Task <long> LocateDateBound(IPositionedMessagesReader reader, DateTime date, ValueBound bound, CancellationToken cancellation)
        {
            var d = new MessageTimestamp(date);

            long begin = reader.BeginPosition;
            long end   = reader.EndPosition;

            long pos   = begin;
            long count = end - begin;

            for (; 0 < count;)
            {
                long count2 = count / 2;

                MessageTimestamp d2        = (await ReadNearestMessageTimestamp(reader, pos + count2)).GetValueOrDefault(MessageTimestamp.MaxValue);
                bool             moveRight = false;
                switch (bound)
                {
                case ValueBound.Lower:
                case ValueBound.UpperReversed:
                    moveRight = d2 < d;
                    break;

                case ValueBound.Upper:
                case ValueBound.LowerReversed:
                    moveRight = d2 <= d;
                    break;
                }
                if (moveRight)
                {
                    pos   += count2 + 1;
                    count -= count2 + 1;
                }
                else
                {
                    count = count2;
                }

                cancellation.ThrowIfCancellationRequested();
            }

            if (bound == ValueBound.LowerReversed || bound == ValueBound.UpperReversed)
            {
                long?tmp = await FindPrevMessagePosition(reader, pos);

                if (tmp == null)
                {
                    return(begin - 1);
                }
                pos = tmp.Value;
            }

            return(pos);
        }
Пример #5
0
        internal static bool EqualStrict(MessageTimestamp t1, MessageTimestamp t2)
        {
            DateTime d1 = t1.data;
            DateTime d2 = t2.data;

            if (d1.Kind != d2.Kind)
            {
                return(false);
            }
            return(d1 == d2);
        }
Пример #6
0
 public MessageBase(long position, long endPosition, IThread t, MessageTimestamp time, StringSlice rawText = new StringSlice())
 {
     if (endPosition < position)
     {
         throw new ArgumentException("bad message positions");
     }
     this.thread      = t;
     this.time        = time;
     this.position    = position;
     this.endPosition = endPosition;
     this.rawText     = rawText;
 }
Пример #7
0
 void MoveRangeToTime(MessageTimestamp time)
 {
     begin = end;
     while (begin < items.Count && items[begin].Time < time)
     {
         ++begin;
     }
     current = begin < items.Count ? items[begin].Time : MessageTimestamp.MaxValue;
     end     = begin;
     while (end < items.Count && MessageTimestamp.Compare(items[end].Time, current) == 0)
     {
         ++end;
     }
 }
Пример #8
0
        static public int Compare(IMessage m1, IMessage m2, bool ignoreConnectionIds = false)
        {
            int sign = MessageTimestamp.Compare(m1.Time, m2.Time);

            if (sign == 0)
            {
                sign = ignoreConnectionIds ? 0 : CompareLogSourceConnectionIds(m1.GetConnectionId(), m2.GetConnectionId());
                if (sign == 0)
                {
                    sign = Math.Sign(m1.Position - m2.Position);
                }
            }
            return(sign);
        }
Пример #9
0
        public static bool TryParse(string str, out ITimeOffsets value)
        {
            value = null;
            if (str == null)
            {
                return(false);
            }
            var  entries   = new List <Entry>();
            bool firstPart = true;

            foreach (var part in str.Split(','))
            {
                var entry = new Entry();
                if (firstPart)
                {
                    firstPart = false;
                    if (!TimeSpan.TryParseExact(part, "c", null, out entry.offset))
                    {
                        return(false);
                    }
                    entry.at = DateTime.MinValue;
                }
                else
                {
                    var components = part.Split('=');
                    if (components.Length != 2)
                    {
                        return(false);
                    }
                    if (!TimeSpan.TryParseExact(components[1], "c", null, out entry.offset))
                    {
                        return(false);
                    }
                    entry.at = MessageTimestamp.ParseFromLoselessFormat(components[0]).ToUnspecifiedTime();
                }
                entries.Add(entry);
            }
            if (entries.Count == 0)
            {
                return(false);
            }
            entries.Sort((e1, e2) => Math.Sign(e2.at.Ticks - e1.at.Ticks));
            value = new TimeOffsets(entries);
            return(true);
        }
Пример #10
0
        static public int Compare(IBookmark b1, IBookmark b2, bool ignoreConnectionIds = false)
        {
            int sign = MessageTimestamp.Compare(b1.Time, b2.Time);

            if (sign == 0)
            {
                sign = ignoreConnectionIds ? 0 : CompareLogSourceConnectionIds(b1.LogSourceConnectionId, b2.LogSourceConnectionId);
                if (sign == 0)
                {
                    sign = Math.Sign(b1.Position - b2.Position);
                    if (sign == 0)
                    {
                        sign = Math.Sign(b1.LineIndex - b2.LineIndex);
                    }
                }
            }
            return(sign);
        }
Пример #11
0
            public int Compare(LogPart x, LogPart y)
            {
                int tmp;

                tmp = MessageTimestamp.Compare(x.FirstMessageTime, y.FirstMessageTime);
                if (tmp != 0)
                {
                    return(tmp);
                }

                tmp = string.Compare(x.FileName, y.FileName, true);
                if (tmp != 0)
                {
                    return(tmp);
                }

                return(tmp);
            }
Пример #12
0
        public static int Compare(MessageTimestamp t1, MessageTimestamp t2)
        {
            DateTime     d1 = t1.data;
            DateTime     d2 = t2.data;
            DateTimeKind k1 = d1.Kind;
            DateTimeKind k2 = d2.Kind;

            if (NormalizeKindForComparision(k1) == NormalizeKindForComparision(k2))
            {
                return(DateTime.Compare(d1, d2));
            }
            if (k1 == DateTimeKind.Utc)
            {
                d1 = t1.ToLocalDateTime();
            }
            else
            {
                d2 = t2.ToLocalDateTime();
            }
            return(DateTime.Compare(d1, d2));
        }
Пример #13
0
            int IComparer <Entry> .Compare(Entry e1, Entry e2)
            {
                int cmpResult;

                long idxDiff = e1.index - e2.index;

                if (Math.Abs(idxDiff) > bufferSize)
                {
                    return(Math.Sign(idxDiff));
                }

                var x = e1.data;
                var y = e2.data;

                cmpResult = inversionFlag * MessageTimestamp.Compare(x.Message.Time, y.Message.Time);
                if (cmpResult != 0)
                {
                    return(cmpResult);
                }

                cmpResult = inversionFlag * Math.Sign(x.Message.Position - y.Message.Position);
                return(cmpResult);
            }
Пример #14
0
            bool HandleResponse(DateBoundPositionResponseData res, bool reversedMode)
            {
                using (trace.NewFrame)
                {
                    Predicate <MessageTimestamp> shouldAdvanceDate = d =>
                                                                     reversedMode ? d > currentDate : d < currentDate;

                    bool readerAdvanced = false;

                    trace.Info("reader returned ({0}, {1})", res.Position, res.Message?.Time);

                    trace.Info("reader's current position: {0}", currentPosition);

                    bool advancePosition = true;
                    if (reversedMode)
                    {
                        if (res.IsBeforeBeginPosition)
                        {
                            trace.Info("it's invalid position (before begin)");
                            advancePosition = false;
                        }
                    }
                    else
                    {
                        if (res.IsEndPosition)
                        {
                            trace.Info("it's invalid position (end)");
                            advancePosition = false;
                        }
                    }
                    if (advancePosition && res.Position > currentPosition)
                    {
                        trace.Info("reader has advanced its position: {0}", res.Position);
                        readerAdvanced  = true;
                        currentPosition = res.Position;
                    }

                    bool advanceDate;
                    if (res.Message == null)
                    {
                        advanceDate = false;
                    }
                    else
                    {
                        advanceDate = shouldAdvanceDate(res.Message.Time);
                    }

                    if (advanceDate)
                    {
                        trace.Info("reader might need to advance the current date from {0} to {1}. Getting writer lock to make final decision...", currentDate, res.Message.Time);

                        if (shouldAdvanceDate(res.Message.Time))
                        {
                            trace.Info("reader is really advancing the current date from {0} to {1}", currentDate, res.Message.Time);
                            currentDate = res.Message.Time;
                        }
                        else
                        {
                            trace.Info("false alarm: reader is not advancing the current date because it has been already advanced to {0} by some other reader", currentDate);
                        }
                    }

                    return(readerAdvanced);
                }
            }
Пример #15
0
 IBookmark IBookmarksFactory.CreateBookmark(MessageTimestamp time)
 {
     return(new Bookmark(time));
 }
Пример #16
0
 public Bookmark(MessageTimestamp time)
     : this(time, null, null, null, 0, 0)
 {
 }
Пример #17
0
 public Bookmark(MessageTimestamp time, string sourceConnectionId, long position, int lineIndex) :
     this(time, null, sourceConnectionId, "", "", position, lineIndex)
 {
 }
Пример #18
0
 public Bookmark(MessageTimestamp time, IThread thread, string displayName, string messageText, long position, int lineIndex) :
     this(time, thread, thread != null && !thread.IsDisposed && thread.LogSource != null ? thread.LogSource.Provider.ConnectionId : "", displayName, messageText, position, lineIndex)
 {
 }
Пример #19
0
 IBookmark IBookmarksFactory.CreateBookmark(MessageTimestamp time, IThread thread, string displayName, long position, int lineIndex)
 {
     return(new Bookmark(time, thread, displayName, position, lineIndex));
 }
Пример #20
0
 IBookmark IBookmarksFactory.CreateBookmark(MessageTimestamp time, string sourceConnectionId, long position, int lineIndex)
 {
     return(new Bookmark(time, sourceConnectionId, position, lineIndex));
 }
Пример #21
0
            public async Task <ResultCode> MoveToDateBound(DateTime d, bool reversedMode)
            {
                using (trace.NewFrame)
                {
                    trace.Info("Moving to the date {0} than '{1}' by sending 'get {2} bound' request to all readers",
                               reversedMode ? "less (or eq)" : "greater (or eq)", d, reversedMode ? "lower (rev)" : "lower");

                    ResultCode resultCode;

                    if (reversedMode)
                    {
                        currentDate = MessageTimestamp.MinValue;
                    }
                    else
                    {
                        currentDate = MessageTimestamp.MaxValue;
                    }

                    Task <DateBoundPositionResponseData> getBoundsTask = null;

                    for (int iteration = 0; ; ++iteration)
                    {
                        trace.Info("it's iteration {0} of trying to send the 'get date bound' request to reader", iteration);
                        var modelThreadCall = invoke.Invoke(() =>
                        {
                            // This code must be executing in the model thread
                            using (trace.NewFrame)
                            {
                                if (source.IsDisposed)
                                {
                                    trace.Warning("reader is disposed");
                                    // This TimeGapsDetector is probably disposed too or will be soon.
                                    // Returning null will make the main algorithm wait.
                                    // During waiting it'll detect stop condition.
                                    return(null);
                                }
                                trace.Info("the reader is idling. Getting date bound.");
                                return(source.GetDateBoundPosition(d,
                                                                   reversedMode ?  ValueBound.LowerReversed : ValueBound.Lower,
                                                                   CancellationToken.None
                                                                   )); // todo: cancellation
                            }
                        });

                        trace.Info("waiting the completion of 'get date bound' request scheduler");
                        if (IsStopOrInvalidate(resultCode = await owner.WaitEvents(Timeout.Infinite, modelThreadCall)))
                        {
                            return(resultCode);
                        }

                        getBoundsTask = await modelThreadCall;

                        if (getBoundsTask != null)
                        {
                            trace.Info("the 'get date bound' request was successfully sent to reader.");
                            break;
                        }

                        trace.Info("reader is not handled. Waiting...");

                        if (IsStopOrInvalidate(resultCode = await owner.WaitEvents(1000, null)))
                        {
                            return(resultCode);
                        }
                    }

                    trace.Info("waiting for the response from the reader");
                    if (IsStopOrInvalidate(resultCode = await owner.WaitEvents(30000, getBoundsTask)))
                    {
                        return(resultCode);
                    }
                    if (resultCode != ResultCode.UserEvent)
                    {
                        trace.Warning("reader didn't respond. Giving up by invalidating current progress.");
                        return(ResultCode.Invalidate);
                    }

                    bool ret = HandleResponse(await getBoundsTask, reversedMode);

                    trace.Info("returning {0}", ret);

                    return(ret ? ResultCode.Ok : ResultCode.None);
                }
            }
Пример #22
0
        bool UpdateAvailableTime(bool incrementalMode)
        {
            bool itIsFirstUpdate = firstUpdateFlag;

            firstUpdateFlag = false;

            UpdateBoundsStatus status = reader.UpdateAvailableBounds(incrementalMode);

            if (status == UpdateBoundsStatus.NothingUpdated && incrementalMode)
            {
                return(false);
            }

            if (status == UpdateBoundsStatus.OldMessagesAreInvalid)
            {
                incrementalMode = false;
            }

            // Get new boundary values into temporary variables
            IMessage newFirst, newLast;

            PositionedMessagesUtils.GetBoundaryMessages(reader, null, out newFirst, out newLast);

            if (firstMessage != null)
            {
                if (newFirst == null || MessageTimestamp.Compare(newFirst.Time, firstMessage.Time) != 0)
                {
                    // The first message we've just read differs from the cached one.
                    // This means that the log was overwritten. Fall to non-incremental mode.
                    incrementalMode = false;
                }
            }

            if (!incrementalMode)
            {
                if (!itIsFirstUpdate)
                {
                    // Reset everything that has been loaded so far
                    InvalidateEverythingThatHasBeenLoaded();
                }
                firstMessage = null;
            }

            // Try to get the dates range for new bounday messages
            DateRange newAvailTime = GetAvailableDateRangeHelper(newFirst, newLast);

            firstMessage = newFirst;

            // Getting here means that the boundaries changed.
            // Fire the notfication.

            var positionsRange = new FileRange.Range(reader.BeginPosition, reader.EndPosition);

            if (!incrementalMode)
            {
                readerContentsEtag = reader.GetContentsEtag();
            }

            int contentsEtag =
                readerContentsEtag
                ^ positionsRange.Begin.GetHashCode()
                ^ positionsRange.End.GetHashCode();

            StatsTransaction(stats =>
            {
                stats.AvailableTime    = newAvailTime;
                LogProviderStatsFlag f = LogProviderStatsFlag.AvailableTime;
                if (incrementalMode)
                {
                    f |= LogProviderStatsFlag.AvailableTimeUpdatedIncrementallyFlag;
                }
                stats.TotalBytes = reader.SizeInBytes;
                f |= LogProviderStatsFlag.BytesCount;
                stats.PositionsRange = positionsRange;
                f |= LogProviderStatsFlag.PositionsRange;
                stats.PositionsRangeUpdatesCount++;
                if (stats.ContentsEtag == null || contentsEtag != stats.ContentsEtag.Value)
                {
                    stats.ContentsEtag = contentsEtag;
                    f |= LogProviderStatsFlag.ContentsEtag;
                }
                return(f);
            });

            return(true);
        }
Пример #23
0
        async Task <ResultCode> FindGaps(DateRange range, TimeSpan threshold, int?maxGapsCount, List <TimeGap> ret)
        {
            using (trace.NewFrame)
            {
                trace.Info("threshold={0}", threshold.ToString());

                if (threshold.Ticks == 0)
                {
                    trace.Warning("threshold is empty");
                    return(ResultCode.None);
                }

                ResultCode resultCode = ResultCode.None;

                Helper helper = new Helper(this);

                // Below is the actual algorithm of finding the gaps:
                // - we start from the begin of the range (d = range.Begin).
                //   On the first iteration we find the positions of the messages
                //   that have the date less than d.
                // - on the next iterations we are finding out if there are messages
                //   with the date less than (d + threshold) with position different from
                //   the current positions. If yes, then there is no gap on
                //   interval (d, d + threshold).
                // - If no messages are found on the interval then we encountered with
                //   a time gap. The end of the gap is located by searching for the
                //   first message that is greater than d.
                TimeSpan cumulativeGapsLen = new TimeSpan();
                for (DateTime d = range.Begin; d < range.End;)
                {
                    trace.Info("moving to the lower bound of {0}", d);

                    if (IsStopOrInvalidate(resultCode = await helper.MoveToDateBound(d, reversedMode: true)))
                    {
                        return(resultCode);
                    }
                    if (resultCode == ResultCode.Ok)
                    {
                        trace.Info("moved successfully. The lower bound is {0}.", helper.CurrentDate);
                        d = helper.CurrentDate.Advance(threshold).ToLocalDateTime();
                    }
                    else
                    {
                        var gapBegin = helper.CurrentDate.ToLocalDateTime();
                        // A tick is needed here because CurrentDate is a date of an existing message.
                        // The gap begins right after this date. This tick matters when
                        // we are comparing gap's date range with a date range of messages.
                        // Do not forget: date ranges use the idea that DateRange.End doesn't belong
                        // to the range.
                        gapBegin = gapBegin.AddTicks(1);
                        trace.Info("no readers advanced. It's time gap starting at {0}", gapBegin);

                        trace.Info("moving to the date greater than {0}", d);
                        if (IsStopOrInvalidate(resultCode = await helper.MoveToDateBound(d, reversedMode: false)))
                        {
                            return(resultCode);
                        }

                        DateTime gapEnd = helper.CurrentDate.ToLocalDateTime();
                        trace.Info("the end of the gap: {0}", gapEnd);

                        if (MessageTimestamp.Compare(helper.CurrentDate, MessageTimestamp.MaxValue) != 0)
                        {
                            d = helper.CurrentDate.Advance(threshold).ToLocalDateTime();
                        }
                        else
                        {
                            d = DateTime.MaxValue;
                        }

                        var gap = new TimeGap(new DateRange(gapBegin, gapEnd));
                        trace.Info("creating new gap {0}", gap);

                        ret.Add(gap);

                        if (maxGapsCount.HasValue && ret.Count > maxGapsCount.Value)
                        {
                            throw new TooManyGapsException();
                        }

                        cumulativeGapsLen += gap.Range.Length;
                    }
                }

                trace.Info("returning {0} gaps", ret.Count);

                return(ResultCode.None);
            }
        }