diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/FontCache/FontSource.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/FontCache/FontSource.cs index 4e19fc8aa08..b2f52261ef4 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/FontCache/FontSource.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/FontCache/FontSource.cs @@ -166,9 +166,9 @@ public UnmanagedMemoryStream GetUnmanagedStream() byte[] bits; // Try our cache first. - lock (_resourceCache) + lock (s_resourceCache) { - bits = _resourceCache.Get(_fontUri); + bits = s_resourceCache.Get(_fontUri); } if (bits == null) @@ -202,9 +202,9 @@ public UnmanagedMemoryStream GetUnmanagedStream() fontStream?.Close(); } - lock (_resourceCache) + lock (s_resourceCache) { - _resourceCache.Add(_fontUri, bits, false); + s_resourceCache.Add(_fontUri, bits, false); } return ByteArrayToUnmanagedStream(bits); @@ -239,9 +239,9 @@ public Stream GetStream() byte[] bits; // Try our cache first. - lock (_resourceCache) + lock (s_resourceCache) { - bits = _resourceCache.Get(_fontUri); + bits = s_resourceCache.Get(_fontUri); } if (bits != null) @@ -423,7 +423,7 @@ protected override void Dispose(bool disposing) private Uri _fontUri; - private static SizeLimitedCache _resourceCache = new SizeLimitedCache(MaximumCacheItems); + private static readonly SizeLimitedCache s_resourceCache = new(MaximumCacheItems); /// /// The maximum number of fonts downloaded from pack:// Uris. diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Shaping/GlyphingCache.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Shaping/GlyphingCache.cs index a3cbd9b1f9f..2bada6fe320 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Shaping/GlyphingCache.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Shaping/GlyphingCache.cs @@ -30,7 +30,7 @@ namespace MS.Internal.Shaping /// internal class GlyphingCache { - private SizeLimitedCache _sizeLimitedCache; + private readonly SizeLimitedCache _sizeLimitedCache; internal GlyphingCache(int capacity) { diff --git a/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/SizeLimitedCache.cs b/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/SizeLimitedCache.cs index d471279e4b9..6ac9ea7091d 100644 --- a/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/SizeLimitedCache.cs +++ b/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/SizeLimitedCache.cs @@ -20,7 +20,7 @@ namespace MS.Internal /// changed, it gets moved to the end of the list. Also, permanent items, /// though in the hash table, are NOT in the linked list. /// - internal class SizeLimitedCache + internal sealed class SizeLimitedCache { //***************************************************** // Constructors @@ -40,12 +40,13 @@ public SizeLimitedCache(int maximumItems) _permanentCount = 0; // set up an empty list. - // the _begin and _end nodes are empty nodes marking the begin and - // end of the list. + // the _begin and _end nodes are empty nodes marking the begin and end of the list. _begin = new Node(default(K), default(V), false); _end = new Node(default(K), default(V), false); - _begin.Next = _end; + + _begin.Next = _end; _end.Previous = _begin; + _nodeLookup = new Dictionary(); } @@ -85,20 +86,13 @@ public int MaximumItems /// public void Add(K key, V resource, bool isPermanent) { + ArgumentNullException.ThrowIfNull(key, nameof(key)); + ArgumentNullException.ThrowIfNull(resource, nameof(resource)); - if ( (object)key == null) - { - throw new ArgumentNullException(nameof(key)); - } - if ( (object)resource == null) - { - throw new ArgumentNullException(nameof(resource)); - } - - // note: [] throws, thus we should check if its in the dictionary first. - if (!_nodeLookup.ContainsKey(key)) + // Lookup first + if (!_nodeLookup.TryGetValue(key, out Node node)) { - Node node = new Node(key, resource, isPermanent); + node = new Node(key, resource, isPermanent); if (!isPermanent) { if (IsFull()) @@ -111,11 +105,11 @@ public void Add(K key, V resource, bool isPermanent) { _permanentCount++; } + _nodeLookup[key] = node; } else { - Node node = _nodeLookup[key]; if (!node.IsPermanent) { RemoveFromList(node); @@ -151,27 +145,15 @@ public void Add(K key, V resource, bool isPermanent) /// public void Remove(K key) { - if ( (object)key == null) - { - throw new ArgumentNullException(nameof(key)); - } + ArgumentNullException.ThrowIfNull(key, nameof(key)); - // note: [] throws, thus we should check if its in the dictionary first. - if (!_nodeLookup.ContainsKey(key)) - { + if (!_nodeLookup.Remove(key, out Node node)) return; - } - Node node = _nodeLookup[key]; - _nodeLookup.Remove(key); if (!node.IsPermanent) - { RemoveFromList(node); - } else - { _permanentCount--; - } } /// @@ -187,17 +169,10 @@ public void Remove(K key) /// public V Get(K key) { - if ( (object)key == null) - { - throw new ArgumentNullException(nameof(key)); - } + ArgumentNullException.ThrowIfNull(key, nameof(key)); - // note: [] throws, thus we should check if its in the dictionary first. - if (!_nodeLookup.ContainsKey(key)) - { - return default(V); - } - Node node = _nodeLookup[key]; + if (!_nodeLookup.TryGetValue(key, out Node node)) + return default; if (!node.IsPermanent) { @@ -218,7 +193,9 @@ public V Get(K key) private void RemoveOldest() { Node node = _begin.Next; + _nodeLookup.Remove(node.Key); + RemoveFromList(node); } @@ -232,6 +209,7 @@ private void InsertAtEnd(Node node) { node.Next = _end; node.Previous = _end.Previous; + node.Previous.Next = node; _end.Previous = node; } @@ -242,7 +220,7 @@ private void InsertAtEnd(Node node) /// /// The node to remove /// - private void RemoveFromList(Node node) + private static void RemoveFromList(Node node) { node.Previous.Next = node.Next; node.Next.Previous = node.Previous; @@ -257,13 +235,13 @@ private void RemoveFromList(Node node) /// private bool IsFull() { - return (_nodeLookup.Count - _permanentCount >= _maximumItems); + return (_nodeLookup.Count - _permanentCount) >= _maximumItems; } /// /// Doubly linked list node class. Has 3 values: key, resource, permanence flag /// - private class Node + private sealed class Node { public Node(K key, V resource, bool isPermanent) { @@ -272,59 +250,34 @@ public Node(K key, V resource, bool isPermanent) IsPermanent = isPermanent; } - public K Key - { - get { return _key; } - set { _key = value; } - } + public K Key { get; } - public V Resource - { - get { return _resource; } - set { _resource = value; } - } + public V Resource { get; set; } - public bool IsPermanent - { - get { return _isPermanent; } - set { _isPermanent = value; } - } + public bool IsPermanent { get; set; } - public Node Next - { - get { return _next; } - set { _next = value; } - } + public Node Next { get; set; } - public Node Previous - { - get { return _previous; } - set { _previous = value; } - } + public Node Previous { get; set; } - private V _resource; - private K _key; - private bool _isPermanent; - private Node _next; - private Node _previous; } //***************************************************** // Private Fields // **************************************************** - // the maximum nonpermanent items allowed - private int _maximumItems; - // need to keep a separate counter for permanent items private int _permanentCount; + // the maximum nonpermanent items allowed + private readonly int _maximumItems; + // the _begin and _end nodes are empty nodes marking the begin and // end of the list. - private Node _begin; - private Node _end; + private readonly Node _begin; + private readonly Node _end; // the hashtable mapping keys to nodes - private Dictionary _nodeLookup; + private readonly Dictionary _nodeLookup; } }