From 0f3dd7eb9547fbb4c95872665f34488d9587dcff Mon Sep 17 00:00:00 2001 From: h3xds1nz Date: Mon, 7 Apr 2025 16:00:06 +0200 Subject: [PATCH 1/4] Swap Dictionary with HashSet --- .../Serialization/TreeWalkProgress.cs | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs index fa08a5dce92..991107252c2 100644 --- a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs +++ b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. /*++ @@ -15,15 +15,17 @@ namespace System.Windows.Xps.Serialization /// This class is used by the Xps Serialization APIs for tracking cycles in a visual tree. /// internal class TreeWalkProgress - { + { + private readonly HashSet _cyclicBrushes = new(); + public bool EnterTreeWalk(ICyclicBrush brush) { - if(this._cyclicBrushes.ContainsKey(brush)) + if(this._cyclicBrushes.Contains(brush)) { return false; } - this._cyclicBrushes.Add(brush, EmptyStruct.Default); + this._cyclicBrushes.Add(brush); return true; } @@ -34,18 +36,7 @@ public void ExitTreeWalk(ICyclicBrush brush) public bool IsTreeWalkInProgress(ICyclicBrush brush) { - return this._cyclicBrushes.ContainsKey(brush); - } - - // We use the keys of this dictionary to simulate a set - // We do not use HashSet to avoid a perf regression by loading System.Core.dll - // It also makes the fix easier to backport to pre .net 3.5 releases - private IDictionary _cyclicBrushes = new Dictionary(); - - // A struct that when optimized does not consume per instance heap\stack space - private struct EmptyStruct - { - public static EmptyStruct Default = new EmptyStruct(); + return this._cyclicBrushes.Contains(brush); } } } From a2f089d14e9e007cde0765a1195a1e177f88850b Mon Sep 17 00:00:00 2001 From: h3xds1nz Date: Mon, 7 Apr 2025 16:00:46 +0200 Subject: [PATCH 2/4] Remove this, fix formatting --- .../Serialization/TreeWalkProgress.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs index 991107252c2..f7f4ac12e08 100644 --- a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs +++ b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs @@ -20,23 +20,23 @@ internal class TreeWalkProgress public bool EnterTreeWalk(ICyclicBrush brush) { - if(this._cyclicBrushes.Contains(brush)) + if (_cyclicBrushes.Contains(brush)) { return false; } - - this._cyclicBrushes.Add(brush); + + _cyclicBrushes.Add(brush); return true; } - + public void ExitTreeWalk(ICyclicBrush brush) { - this._cyclicBrushes.Remove(brush); + _cyclicBrushes.Remove(brush); } - + public bool IsTreeWalkInProgress(ICyclicBrush brush) { - return this._cyclicBrushes.Contains(brush); + return _cyclicBrushes.Contains(brush); } } } From 2bf937200eca19832a4c209961965f8646d1063b Mon Sep 17 00:00:00 2001 From: h3xds1nz Date: Mon, 7 Apr 2025 16:01:41 +0200 Subject: [PATCH 3/4] Seal the class, avoid double lookup --- .../ReachFramework/Serialization/TreeWalkProgress.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs index f7f4ac12e08..f1361fe690b 100644 --- a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs +++ b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs @@ -12,21 +12,15 @@ This file implements the TreeWalkProgress namespace System.Windows.Xps.Serialization { /// - /// This class is used by the Xps Serialization APIs for tracking cycles in a visual tree. + /// This class is used by the Xps Serialization APIs for tracking cycles in a visual tree. /// - internal class TreeWalkProgress + internal sealed class TreeWalkProgress { private readonly HashSet _cyclicBrushes = new(); public bool EnterTreeWalk(ICyclicBrush brush) { - if (_cyclicBrushes.Contains(brush)) - { - return false; - } - - _cyclicBrushes.Add(brush); - return true; + return _cyclicBrushes.Add(brush); } public void ExitTreeWalk(ICyclicBrush brush) From 93e465de8507d030d9b31504b08e6a6b42d88c60 Mon Sep 17 00:00:00 2001 From: h3xds1nz Date: Mon, 7 Apr 2025 16:01:57 +0200 Subject: [PATCH 4/4] Flatten namespace --- .../Serialization/TreeWalkProgress.cs | 43 ++++++++----------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs index f1361fe690b..655ac766247 100644 --- a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs +++ b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Serialization/TreeWalkProgress.cs @@ -1,36 +1,29 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -/*++ - - Abstract: - This file implements the TreeWalkProgress - used by the Xps Serialization APIs for tracking cycles in a visual tree. ---*/ using System.Windows.Media; -namespace System.Windows.Xps.Serialization +namespace System.Windows.Xps.Serialization; + +/// +/// This class is used by the Xps Serialization APIs for tracking cycles in a visual tree. +/// +internal sealed class TreeWalkProgress { - /// - /// This class is used by the Xps Serialization APIs for tracking cycles in a visual tree. - /// - internal sealed class TreeWalkProgress - { - private readonly HashSet _cyclicBrushes = new(); + private readonly HashSet _cyclicBrushes = new(); - public bool EnterTreeWalk(ICyclicBrush brush) - { - return _cyclicBrushes.Add(brush); - } + public bool EnterTreeWalk(ICyclicBrush brush) + { + return _cyclicBrushes.Add(brush); + } - public void ExitTreeWalk(ICyclicBrush brush) - { - _cyclicBrushes.Remove(brush); - } + public void ExitTreeWalk(ICyclicBrush brush) + { + _cyclicBrushes.Remove(brush); + } - public bool IsTreeWalkInProgress(ICyclicBrush brush) - { - return _cyclicBrushes.Contains(brush); - } + public bool IsTreeWalkInProgress(ICyclicBrush brush) + { + return _cyclicBrushes.Contains(brush); } }