From 0e529b127f3e5a10dc3b45bccc3b2f8ce1e25b54 Mon Sep 17 00:00:00 2001 From: Nemanja Petrovic Date: Thu, 20 Mar 2025 15:52:31 +0100 Subject: [PATCH 1/2] Refactor CustomRedirectCollection for reverse sorting Replaced the Dictionary for URL lookups with a SortedDictionary that sorts URLs in reverse order (Z-A). Removed the _quickLookupTable and updated methods to work with the new _redirectsZA structure. Added ReverseStringComparer class for custom string comparison. --- .../Redirects/CustomRedirectCollection.cs | 30 ++++--------------- .../Core/Redirects/ReverseStringComparer.cs | 27 +++++++++++++++++ 2 files changed, 32 insertions(+), 25 deletions(-) create mode 100644 src/Geta.NotFoundHandler/Core/Redirects/ReverseStringComparer.cs diff --git a/src/Geta.NotFoundHandler/Core/Redirects/CustomRedirectCollection.cs b/src/Geta.NotFoundHandler/Core/Redirects/CustomRedirectCollection.cs index fa782aa..ed79da1 100644 --- a/src/Geta.NotFoundHandler/Core/Redirects/CustomRedirectCollection.cs +++ b/src/Geta.NotFoundHandler/Core/Redirects/CustomRedirectCollection.cs @@ -18,15 +18,10 @@ public class CustomRedirectCollection : IEnumerable { private readonly IEnumerable _providers = new List(); - /// - /// Hashtable for quick lookup of old urls - /// - private readonly Dictionary _quickLookupTable = new(StringComparer.OrdinalIgnoreCase); - /// /// Cache of URLs sorted ZA for look up of partially matched URLs /// - private KeyValuePair[] _redirectsZACache; + private readonly SortedDictionary _redirectsZA = new(new ReverseStringComparer()); public CustomRedirectCollection() { @@ -39,7 +34,7 @@ public CustomRedirectCollection(IEnumerable providers) public IEnumerator GetEnumerator() { - return _quickLookupTable.Values.GetEnumerator(); + return _redirectsZA.Values.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() @@ -79,34 +74,19 @@ public CustomRedirect Find(Uri urlNotFound) public void Add(CustomRedirect customRedirect) { var oldUrl = HttpUtility.UrlDecode(customRedirect.OldUrl); - if (_quickLookupTable.ContainsKey(oldUrl)) - { - _quickLookupTable[oldUrl] = customRedirect; - return; - } - - // Add to quick look up table too - _quickLookupTable.Add(oldUrl, customRedirect); - - // clean cache - _redirectsZACache = null; + _redirectsZA[oldUrl] = customRedirect; } private CustomRedirect FindInternal(string url) { url = HttpUtility.UrlDecode(url) ?? string.Empty; - if (_quickLookupTable.TryGetValue(url, out var redirect)) + if (_redirectsZA.TryGetValue(url, out var redirect)) { return redirect; } // working with local copy to avoid multi-threading issues - var redirectsZA = _redirectsZACache; - if (redirectsZA == null) - { - redirectsZA = _quickLookupTable.OrderByDescending(x => x.Key, StringComparer.OrdinalIgnoreCase).ToArray(); - _redirectsZACache = redirectsZA; - } + var redirectsZA = _redirectsZA.ToArray(); var path = url.AsPathSpan(); var query = url.AsQuerySpan(); diff --git a/src/Geta.NotFoundHandler/Core/Redirects/ReverseStringComparer.cs b/src/Geta.NotFoundHandler/Core/Redirects/ReverseStringComparer.cs new file mode 100644 index 0000000..8175f3b --- /dev/null +++ b/src/Geta.NotFoundHandler/Core/Redirects/ReverseStringComparer.cs @@ -0,0 +1,27 @@ +// Copyright (c) Geta Digital. All rights reserved. +// Licensed under Apache-2.0. See the LICENSE file in the project root for more information + +using System; +using System.Collections.Generic; + +namespace Geta.NotFoundHandler.Core.Redirects; + +/// +/// A comparer that sorts strings in reverse order. +/// +public class ReverseStringComparer : IComparer +{ + private readonly IComparer _baseComparer; + + public ReverseStringComparer() : this(StringComparer.OrdinalIgnoreCase) { } + + public ReverseStringComparer(IComparer baseComparer) + { + _baseComparer = baseComparer ?? throw new ArgumentNullException(nameof(baseComparer)); + } + + public int Compare(string x, string y) + { + return _baseComparer.Compare(y, x); + } +} From 3cb07c33a1128a5ec0bf290468ecf82c5693ed9d Mon Sep 17 00:00:00 2001 From: Nemanja Petrovic Date: Thu, 20 Mar 2025 16:15:20 +0100 Subject: [PATCH 2/2] Modify _redirectsZA summary --- .../Core/Redirects/CustomRedirectCollection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Geta.NotFoundHandler/Core/Redirects/CustomRedirectCollection.cs b/src/Geta.NotFoundHandler/Core/Redirects/CustomRedirectCollection.cs index ed79da1..eca9df4 100644 --- a/src/Geta.NotFoundHandler/Core/Redirects/CustomRedirectCollection.cs +++ b/src/Geta.NotFoundHandler/Core/Redirects/CustomRedirectCollection.cs @@ -19,7 +19,7 @@ public class CustomRedirectCollection : IEnumerable private readonly IEnumerable _providers = new List(); /// - /// Cache of URLs sorted ZA for look up of partially matched URLs + /// URLs sorted Z-A. /// private readonly SortedDictionary _redirectsZA = new(new ReverseStringComparer());