-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect behavior of SortedDictionary when used with OrdinalIgnoreCase comparer #29112
Comments
I spent some time debugging this and here's what I found: I don't think there is a bug in the implementation of SortedDictionary(or SortedSet which is what it leverages). The interesting bit is the following lines: var equal = string.Equals("narınnarın", "narinnarin", StringComparison.OrdinalIgnoreCase);
Console.WriteLine(equal); // True on Mac
var rightCompare = StringComparer.OrdinalIgnoreCase.Compare("naryn", "narınnarın"); // equals -1
var leftCompare = StringComparer.OrdinalIgnoreCase.Compare("naryn", "narinnarin"); // equals 16 This is important because "narınnarın" is the right child of "naryn". When we go looking for "narinnarin", we check Compare("naryn", "narinnarin"). If "narınnarın" and "narinnarin" are indeed equal, we should have gone right at "naryn" and found "narınnarın". Instead, we go left and find null and insert into the SortedSet. Why are rightCompare and leftCompare different? This may be a string compare bug. Tagging @tarekgh to potentially take a look? |
When you are comparing "naryn" and "narınnarın", the first different characters are 'y' and 'ı'. The 'y' ordinal value is 0x79 and the ordinal value of 'ı' is 0x131. This means 'y' < 'ı' which means "naryn" < "narınnarın" and that is why you got negative number. When you are comparing "naryn" and "narinnarin", the first different characters are 'y' and 'i'. The 'y' ordinal value is 0x79 and the ordinal value of 'i' is 0x69. This means 'y' > 'i' which means "naryn" > "narinnarin" and that is why you got positive number. Note, the casing is done only for checking the equality but not for deciding which string less than or greater the other string. |
Seems like it might be an ICU bug? Per @pgovind's comment, the collation engine is returning |
Due to lack of recent activity, this issue has been marked as a candidate for backlog cleanup. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will undo this process. This process is part of our issue cleanup automation. |
Number of entries added to a
SortedDictionary
shouldn't be affected by the order of insertion.The issue is reproducible in non-Windows environments (checked in .NET Core 2.1 / 2.2).
See playground.
There are 5 entries being inserted in the sample below. The dictionary is supposed to have 4 entries, since two records have the equal keys in terms of
OrdinalIgnoreCase
comparer,["narınnarın"] = 3
["narinnarin"] = 4
Proving snippet:
Sample
Actual Output
Expected Output
The text was updated successfully, but these errors were encountered: