public void Register(bool end) { Item2.Add(Item1.ElapsedMilliseconds); if (end) { Item1.Stop(); } else { Item1.Restart(); } }
///// <summary> ///// Creates a new finite-state machine transition. ///// </summary> ///// <param name="initialState">initial state</param> ///// <param name="letters">a list of letters</param> ///// <param name="resultingState">resulting state</param> //public MachineTransition(RegularExpression initialState, IEnumerable<string> letters, // RegularExpression resultingState) // : base(initialState, new List<string>(), resultingState) //{ // AddAllLetters(letters); //} /// <summary> /// Adds a letter to this transition. /// </summary> /// <param name="letter">a letter</param> public void AddLetter(string letter) { Item2.Add(letter); }
public static Expression OptimizeMappingExpressionForSequentialAccess(Expression expression, int fieldCount, bool reduce) { if (reduce) { expression = expression.Transform(e => e is ConvertFromDataReaderExpression conv ? conv.Reduce() : e); } string?failMessage = null; var newVariables = new ParameterExpression?[fieldCount * 2]; var insertedExpressions = new Expression?[fieldCount * 2]; var replacements = new Expression?[fieldCount * 2]; var replacedMethods = new MethodInfo[fieldCount]; var isNullableStruct = new bool[fieldCount]; // slow mode column types Dictionary <int, Tuple <ConvertFromDataReaderExpression.ColumnReader, ISet <Type> > >?slowColumnTypes = null; Expression?dataReaderExpr = null; Func <Expression, Expression> tranformFunc = null !; tranformFunc = e => { if (failMessage != null) { return(e); } if (e is MethodCallExpression call) { // we work only with: // - instance method of data reader // - method, marked with ColumnReaderAttribute // - ColumnReader.GetValueSequential var columnIndex = TryGetColumnIndex(call); if (columnIndex != null) { // test IsDBNull method by-name to support overrides if (call.Object != null && typeof(IDataReader).IsAssignableFrom(call.Object.Type) && call.Method.Name == nameof(IDataReader.IsDBNull)) { var index = columnIndex.Value * 2; if (newVariables[index] == null) { var variable = Expression.Variable(typeof(bool), $"is_null_{columnIndex}"); newVariables[index] = variable; replacements[index] = variable; insertedExpressions[index] = Expression.Assign(variable, call); } return(replacements[index] !); } else { // other methods we treat as Get* methods var index = columnIndex.Value * 2 + 1; if (newVariables[index] == null) { var type = call.Type; ParameterExpression variable; if (newVariables[index - 1] == null) { // no IsDBNull call: column is not nullable // (also could be a bad expression) variable = Expression.Variable(type, $"get_value_{columnIndex}"); insertedExpressions[index] = Expression.Assign(variable, Expression.Convert(call, type)); } else { var isNullable = type.IsValueType && !type.IsNullable(); if (isNullable) { type = typeof(Nullable <>).MakeGenericType(type); isNullableStruct[columnIndex.Value] = true; } variable = Expression.Variable(type, $"get_value_{columnIndex}"); insertedExpressions[index] = Expression.Assign( variable, Expression.Condition( newVariables[index - 1], Expression.Constant(null, type), isNullable ? Expression.Convert(call, type) : call)); } newVariables[index] = variable; replacements[index] = isNullableStruct[columnIndex.Value] ? Expression.Property(variable, "Value") : variable; replacedMethods[columnIndex.Value] = call.Method; } else if (replacedMethods[columnIndex.Value] != call.Method) { // tried to replace multiple methods failMessage = $"Multiple data reader methods called for column: {replacedMethods[columnIndex.Value]} vs {call.Method}"; return(e); } return(replacements[index] !); } } else if (call.Method == Methods.LinqToDB.ColumnReader.GetValueSequential && call.Object is ConstantExpression c3 && c3.Value is ConvertFromDataReaderExpression.ColumnReader columnReader) { columnIndex = columnReader.ColumnIndex; var index = columnIndex.Value * 2 + 1; if (newVariables[index] == null) { newVariables[index] = Expression.Variable(typeof(object), $"get_value_{columnIndex}"); if (slowColumnTypes == null) { slowColumnTypes = new Dictionary <int, Tuple <ConvertFromDataReaderExpression.ColumnReader, ISet <Type> > >(); dataReaderExpr = call.Arguments[0]; } slowColumnTypes.Add(columnIndex.Value, new Tuple <ConvertFromDataReaderExpression.ColumnReader, ISet <Type> >(columnReader, new HashSet <Type>())); } slowColumnTypes ![columnIndex.Value].Item2.Add(columnReader.ColumnType); // replacement expression build later when we know all types return(call.Update( call.Object, call.Arguments.Take(2).Select(a => a.Transform(tranformFunc)).Concat(new[] { newVariables[index] }))); }