public static int Comparison(TimeStamp emp1, TimeStamp emp2) { if (System.Object.ReferenceEquals(emp1, emp2)) { return 0; } if ((Object)emp1 == null || (Object)emp2 == null) { return -1; } if (emp1.Time < emp2.Time) { return -1; } else if (emp1.Time == emp2.Time) { return 0; } else if (emp1.Time > emp2.Time) { return 1; } return 0; }
internal IEnumerable<KeyValuePair<TimeStamp, IPacket>> GetForward(TimeStamp timeStamp) { lock (PacketList) { var finalList = PacketList.Skip(Position + 1).TakeWhile(p => p.Key <= timeStamp); if (finalList.Any()) { // TODO: IndexOfValue is very expensive Position = PacketList.IndexOfValue(finalList.Last().Value); } return finalList; } }
internal IEnumerable<KeyValuePair<TimeStamp, IPacket>> GetBackward(TimeStamp timeStamp) { lock (PacketList) { var finalList = PacketList.Take(Position + 1).SkipWhile(p => p.Key <= timeStamp).Reverse(); if (finalList.Any()) { Position = PacketList.IndexOfValue(finalList.Last().Value) - 1; } return finalList; } }
internal void UpdateSnapshot(Snapshot snapshot, bool forceFullRebuild) { if (SuspendRebuilding) { return; } lock (AddLock) { // Start by rebasing if necessary bool forceUpdate = false; if (RebaseBlocks) { snapshot.Rebase(AddressRange.Min, AddressWidth); RebaseBlocks = false; forceUpdate = true; } UInt64 maxTime = ArtificialMaxTime; if (maxTime == 0) { maxTime = TimeRange.Max; } IEnumerable<KeyValuePair<TimeStamp, IPacket>> packets = null; bool isBackward = false; if (forceFullRebuild) { snapshot.Reset(); packets = Get(); } else { // Determine what entries we need to get based off scrubber position UInt64 timeRange = maxTime - TimeRange.Min; // Readjust the position if needed if (ArtificialMaxTime == 0 && timeRange > 0) { double rangeScale = (double)LastRange / (double)timeRange; if (rangeScale > 0 && Scrubber._Position < 1.0) { // Hacky Scrubber._Position *= rangeScale; Scrubber._Position = Scrubber._Position.Clamp(0.0, 1.0); Scrubber.FlagRedraw(); } } LastRange = timeRange; double position = Scrubber.Position; UInt64 currentTime = TimeRange.Min + (UInt64)((double)timeRange * position); bool nothingToProcess = false; if (currentTime > LastTimestamp.Time) { packets = GetForward(new TimeStamp(currentTime)); } else if (currentTime < LastTimestamp.Time) { packets = GetBackward(new TimeStamp(currentTime)); isBackward = true; } else { nothingToProcess = true; } LastTimestamp = new TimeStamp(currentTime); if (nothingToProcess && !forceUpdate) { return; } } if (AddressRange.Max < AddressRange.Min) { return; } // Create final list, removing allocations as frees are encountered if (packets != null) { int index = 0; foreach (var pair in packets) { // On a full rebuild, if there's a position specified in // the snapshot, only go up to that position if (forceFullRebuild && snapshot.Position > 0) { if (index > snapshot.Position) { break; } } // TODO: Can allocation and free processing be combined? // They should be exact opposites of each other if (pair.Value is Allocation) { Allocation allocation = pair.Value as Allocation; if (!isBackward) { MemoryBlock newBlock = snapshot.Add( allocation, AddressRange.Min, AddressWidth); } else { snapshot.Remove(allocation.Address); } } else { Free free = pair.Value as Free; if (snapshot.Find(free.Address) != null) { MemoryBlock removedBlock = snapshot.Remove(free.Address); if (removedBlock != null) { removedBlock.Allocation.AssociatedFree = free; free.AssociatedAllocation = removedBlock.Allocation; } } else { if (isBackward) { MemoryBlock newBlock = snapshot.Add( free.AssociatedAllocation, AddressRange.Min, AddressWidth); } } } index++; } if (!forceFullRebuild || snapshot.Position == 0) { snapshot.Position = Position; } } if (Rebuilt != null) { EventArgs e = new EventArgs(); Rebuilt.Invoke(this, e); } } //); }