public static IComparer <string> For(int startIndex) { if (!_comparers.TryGetValue(startIndex, out var comparer)) { comparer = new StaticStringDictionaryComparer(startIndex); _comparers.Add(startIndex, comparer); } return(comparer); }
static Expression SwitchOnChar <T>(ParameterExpression keyParameter, Expression defaultExpr, SwitchCase <T>[] switchCases, int index, int lower, int upper) { if (lower == upper) { return(Expression.Condition( Expression.Call(_stringEquals, keyParameter, Expression.Constant(switchCases[lower].Key)), Expression.Convert(Expression.Constant(switchCases[lower].Value), typeof(T)), defaultExpr)); } if (index == switchCases[upper].Key.Length) { return(null); } switchCases = switchCases.Skip(lower).Take(upper - lower + 1) .OrderBy(switchCase => switchCase.Key, StaticStringDictionaryComparer.For(index)).ToArray(); upper = upper - lower; lower = 0; var middle = MidPoint(lower, upper); if (switchCases[lower].Key[index] == switchCases[middle].Key[index]) { var result = SwitchOnChar(keyParameter, defaultExpr, switchCases, index + 1, lower, upper); if (result != null) { return(result); } } middle = GetIndexOfFirstDifferentCaseFromUp(switchCases, lower, middle, upper, switchCase => switchCase.Key[index]); if (middle == -1) { return(null); } var trueBranch = SwitchOnChar(keyParameter, defaultExpr, switchCases, index, lower, middle); if (trueBranch == null) { return(null); } var falseBranch = SwitchOnChar(keyParameter, defaultExpr, switchCases, index, middle + 1, upper); if (falseBranch == null) { return(null); } return(Expression.Condition( Expression.LessThan(Expression.Call(keyParameter, _stringIndex, Expression.Constant(index)), Expression.Constant(switchCases[middle + 1].Key[index])), trueBranch, falseBranch)); }