From 756507c323eac70e6cb326afb4f0f3a28af306ca Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 10 Dec 2015 19:19:45 -0800 Subject: [PATCH] Fix issue in our binary search for a fuzzy name. --- .../FindSymbols/SymbolTree/SymbolTreeInfo.cs | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs index 400baa2980d..5ac6d57baa9 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs @@ -16,7 +16,7 @@ internal partial class SymbolTreeInfo /// /// The list of nodes that represent symbols. The primary key into the sorting of this list is the name. - /// They are sorted case-insensitively with the . Finding case-sensitive + /// They are sorted case-insensitively with the . Finding case-sensitive /// matches can be found by binary searching for something that matches insensitively, and then searching /// around that equivalence class for one that matches. /// @@ -27,6 +27,8 @@ internal partial class SymbolTreeInfo /// private readonly BKTree _bkTree; + private static readonly StringComparer s_caseInsensitiveComparer = CaseInsensitiveComparison.Comparer; + // We first sort in a case insensitive manner. But, within items that match insensitively, // we then sort in a case sensitive manner. This helps for searching as we'll walk all // the items of a specific casing at once. This way features can cache values for that @@ -35,16 +37,14 @@ internal partial class SymbolTreeInfo // they're searching for. However, with this sort of comparison we now get // "prop, prop, Prop, Prop". Features can take advantage of that by caching their previous // result and reusing it when they see they're getting the same string again. - private static readonly Comparison s_nodeSortComparer = (s1, s2) => + private static readonly Comparison s_totalComparer = (s1, s2) => { - var diff = CaseInsensitiveComparison.Comparer.Compare(s1, s2); + var diff = s_caseInsensitiveComparer.Compare(s1, s2); return diff != 0 ? diff : StringComparer.Ordinal.Compare(s1, s2); }; - private static readonly StringComparer s_nodeEquals = CaseInsensitiveComparison.Comparer; - private SymbolTreeInfo(VersionStamp version, IReadOnlyList orderedNodes, BKTree bkTree) { _version = version; @@ -132,10 +132,9 @@ private IEnumerable FindNodes(string name, StringComparer comparer) } int position = startingPosition; - while (position > 0 && s_nodeEquals.Equals(_nodes[position - 1].Name, name)) + while (position > 0 && s_caseInsensitiveComparer.Equals(_nodes[position - 1].Name, name)) { position--; - if (comparer.Equals(_nodes[position].Name, name)) { yield return position; @@ -143,7 +142,7 @@ private IEnumerable FindNodes(string name, StringComparer comparer) } position = startingPosition; - while (position + 1 < _nodes.Count && s_nodeEquals.Equals(_nodes[position + 1].Name, name)) + while (position + 1 < _nodes.Count && s_caseInsensitiveComparer.Equals(_nodes[position + 1].Name, name)) { position++; if (comparer.Equals(_nodes[position].Name, name)) @@ -155,7 +154,7 @@ private IEnumerable FindNodes(string name, StringComparer comparer) } /// - /// Searches for a name in the ordered list that matches per the . + /// Searches for a name in the ordered list that matches per the . /// private int BinarySearch(string name) { @@ -166,7 +165,7 @@ private int BinarySearch(string name) { int mid = min + ((max - min) >> 1); - var comparison = s_nodeSortComparer(_nodes[mid].Name, name); + var comparison = s_caseInsensitiveComparer.Compare(_nodes[mid].Name, name); if (comparison < 0) { min = mid + 1; @@ -280,7 +279,7 @@ private static Node[] SortNodes(List nodes) private static int CompareNodes(Node x, Node y, IReadOnlyList nodeList) { - var comp = s_nodeSortComparer(x.Name, y.Name); + var comp = s_totalComparer(x.Name, y.Name); if (comp == 0) { if (x.ParentIndex != y.ParentIndex) -- GitLab