提交 756507c3 编写于 作者: C Cyrus Najmabadi

Fix issue in our binary search for a fuzzy name.

上级 1aabbde2
......@@ -16,7 +16,7 @@ internal partial class SymbolTreeInfo
/// <summary>
/// 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 <see cref="s_nodeSortComparer" />. Finding case-sensitive
/// They are sorted case-insensitively with the <see cref="s_totalComparer" />. 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.
/// </summary>
......@@ -27,6 +27,8 @@ internal partial class SymbolTreeInfo
/// </summary>
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<string> s_nodeSortComparer = (s1, s2) =>
private static readonly Comparison<string> 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<Node> orderedNodes, BKTree bkTree)
{
_version = version;
......@@ -132,10 +132,9 @@ private IEnumerable<int> 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<int> 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<int> FindNodes(string name, StringComparer comparer)
}
/// <summary>
/// Searches for a name in the ordered list that matches per the <see cref="s_nodeSortComparer" />.
/// Searches for a name in the ordered list that matches per the <see cref="s_caseInsensitiveComparer" />.
/// </summary>
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<Node> nodes)
private static int CompareNodes(Node x, Node y, IReadOnlyList<Node> 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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册