@@ -201,32 +201,40 @@ private int BinarySearch(string prefix)
201201 {
202202 Debug . Assert ( candidate . StartsWith ( prefix , StringComparison . OrdinalIgnoreCase ) ) ;
203203
204- // Okay, now we have a candidate that starts with the prefix. If the candidate is longer than
205- // the prefix, we need to look at the next character and see if it's a delimiter.
206- if ( candidate . Length == prefix . Length )
207- {
208- // Exact match
209- return pivot ;
210- }
211-
212- var c = candidate [ prefix . Length ] ;
213- if ( c == '.' || c == '[' )
204+ // At this point, we have identified a candidate that starts with the given prefix.
205+ // If the candidate's length is greater than that of the prefix, we need to examine
206+ // the character that immediately follows the prefix in the candidate string.
207+ // This step is crucial to determine if the candidate is a valid prefix match.
208+ // A valid prefix match occurs if the next character is either a delimiter ('.' or '['),
209+ // indicating that the candidate is a sub-key of the prefix. If the next character
210+ // is not a delimiter, it means the candidate contains additional characters that
211+ // extend beyond the prefix without forming a valid hierarchical relationship,
212+ // which should not qualify as a prefix match. Therefore, we will continue searching
213+ // for valid matches in this case.
214+
215+ if ( candidate . Length > prefix . Length )
214216 {
215- // Match, followed by delimiter
216- return pivot ;
217+ var c = candidate [ prefix . Length ] ;
218+ if ( c == '.' || c == '[' )
219+ {
220+ // Match, followed by delimiter
221+ return pivot ;
222+ }
223+
224+ // Okay, so the candidate has some extra text. We need to keep searching.
225+ //
226+ // Can often assume the candidate string is greater than the prefix e.g. that works for
227+ // prefix: product
228+ // candidate: productId
229+ // most of the time because "product", "product.id", etc. will sort earlier than "productId". But,
230+ // the assumption isn't correct if "product[0]" is also in _sortedValues because that value will
231+ // sort later than "productId".
232+ //
233+ // Fall back to brute force and cover all the cases.
234+ return LinearSearch ( prefix , start , end ) ;
217235 }
218236
219- // Okay, so the candidate has some extra text. We need to keep searching.
220- //
221- // Can often assume the candidate string is greater than the prefix e.g. that works for
222- // prefix: product
223- // candidate: productId
224- // most of the time because "product", "product.id", etc. will sort earlier than "productId". But,
225- // the assumption isn't correct if "product[0]" is also in _sortedValues because that value will
226- // sort later than "productId".
227- //
228- // Fall back to brute force and cover all the cases.
229- return LinearSearch ( prefix , start , end ) ;
237+ return - 1 ;
230238 }
231239
232240 if ( compare > 0 )
0 commit comments