private static ProfilerBlock DumpRecursive(object owner, SlimProfilerEntry entry, IDictionary <SlimProfilerEntry, ProfilerBlock> result) { if (result.TryGetValue(entry, out ProfilerBlock block)) { return(block); } block = new ProfilerBlock() { TimeElapsed = entry.UpdateTime }; block.SetOwner(owner); result.Add(entry, block); if (entry is FatProfilerEntry fat) { var keys = fat.ChildUpdateKeys(); block.Children = new ProfilerBlock[keys.Count]; var i = 0; foreach (var key in keys) { if (fat.ChildUpdateTime.TryGetValue(key, out SlimProfilerEntry child)) { if (child.UpdateTime > 0) { block.Children[i++] = DumpRecursive(key, child, result); } } } if (i != block.Children.Length) { Array.Resize(ref block.Children, i); } Array.Sort(block.Children, new ProfilerBlockComparer()); } return(block); }
private void UpdateInternal(object owner, SlimProfilerEntry entry, bool forcePropertyUpdate = false) { if (entry == null) { if (!OwnerName.Equals(_noData) || forcePropertyUpdate) { OwnerName = _noData; OnPropertyChanged(nameof(OwnerName)); } // ReSharper disable once CompareOfFloatsByEqualityOperator if (UpdateTime != 0 || forcePropertyUpdate) { UpdateTime = 0; OnPropertyChanged(nameof(UpdateTime)); } if (Children.Count > 0) { Children.Clear(); } return; } string ownerId = ProfilerObjectIdentifier.Identify(owner); if (!ownerId.Equals(OwnerName) || forcePropertyUpdate) { OwnerName = ownerId; OnPropertyChanged(nameof(OwnerName)); } UpdateTime = entry.UpdateTime; OnPropertyChanged(nameof(UpdateTime)); if (entry is FatProfilerEntry fat) { if (ChildrenSorted.IsObserved || Children.IsObserved || forcePropertyUpdate) { _childrenUpdateDeferred = false; ICollection <object> keys = fat.ChildUpdateKeys(); var id = 0; foreach (object key in keys) { if (fat.ChildUpdateTime.TryGetValue(key, out SlimProfilerEntry child) && child.UpdateTime > DisplayTimeThreshold) { if (id >= Children.Count) { var result = new ProfilerEntryViewModel(); result.UpdateInternal(key, child, forcePropertyUpdate); Children.Add(result); id++; } else { Children[id++].UpdateInternal(key, child, forcePropertyUpdate); } } } while (Children.Count > id) { Children.RemoveAt(Children.Count - 1); } using (ChildrenSorted.DeferredUpdate()) { var sortedEnumerable = Children.OrderBy(x => (int)(-x.UpdateTime / DisplayTimeThreshold)); if (Children.Count > PaginationCount) { var pageCount = (int)Math.Ceiling(Children.Count / (float)PaginationCount); if (_wasPaged) { while (ChildrenSorted.Count > pageCount) { ChildrenSorted.RemoveAt(ChildrenSorted.Count - 1); } } else { ChildrenSorted.Clear(); } while (ChildrenSorted.Count < pageCount) { ChildrenSorted.Add(new ProfilerEntryViewModel()); } using (var iterator = sortedEnumerable.GetEnumerator()) { for (var i = 0; i < pageCount; i++) { ChildrenSorted[i].OwnerName = $"Items {i * PaginationCount + 1} to {i * PaginationCount + PaginationCount}"; ChildrenSorted[i].OnPropertyChanged(nameof(OwnerName)); FillPage(ChildrenSorted[i], iterator); } } _wasPaged = true; } else { ChildrenSorted.Clear(); foreach (var k in sortedEnumerable) { ChildrenSorted.Add(k); } _wasPaged = false; } } } else { _childrenUpdateDeferred = true; } } else { Children.Clear(); ChildrenSorted.Clear(); } }