private static IComparerExpression <T> Reverse(IComparerExpression <T> comparer) { Contract.Requires(comparer != null); Expression <Comparison <T> > expression = comparer.GetCompareExpr(); Expression <Comparison <T> > template = (left, right) => CallInliner.Call(expression, right, left); Expression <Comparison <T> > reversedExpression = template.InlineCalls(); return(new ComparerExpression <T>(reversedExpression)); }
public static IComparerExpression <TNewInput> TransformInput <TOldInput, TNewInput>(this IComparerExpression <TOldInput> comparer, Expression <Func <TNewInput, TOldInput> > transform) { Contract.Requires(comparer != null); Contract.Requires(transform != null); var expression = comparer.GetCompareExpr(); Expression <Comparison <TNewInput> > template = (left, right) => CallInliner.Call(expression, CallInliner.Call(transform, left), CallInliner.Call(transform, right)); var transformedExpression = template.InlineCalls(); return(new ComparerExpression <TNewInput>(transformedExpression)); }
private static IComparerExpression <T> ThenOrderBy(IComparerExpression <T> comparer1, IComparerExpression <T> comparer2) { Contract.Requires(comparer1 != null); Contract.Requires(comparer2 != null); Expression <Comparison <T> > primary = comparer1.GetCompareExpr(); Expression <Comparison <T> > secondary = comparer2.GetCompareExpr(); Expression <Comparison <T> > template = (left, right) => CallInliner.Call(primary, left, right) == 0 ? CallInliner.Call(secondary, left, right) : CallInliner.Call(primary, left, right); Expression <Comparison <T> > newExpression = template.InlineCalls(); return(new ComparerExpression <T>(newExpression)); }
public static IAggregate <TInput, NullOutputWrapper <TState>, TResult> OutputDefaultWhenEmpty <TInput, TState, TResult>( this IAggregate <TInput, TState, TResult> aggregate) { Contract.Requires(aggregate != null); Expression <Func <NullOutputWrapper <TState> > > newInitialState = () => new NullOutputWrapper <TState> { Count = 0, State = CallInliner.Call(aggregate.InitialState()) }; Expression <Func <NullOutputWrapper <TState>, long, TInput, NullOutputWrapper <TState> > > newAccumulate = (oldState, timestamp, input) => new NullOutputWrapper <TState> { Count = oldState.Count + 1, State = CallInliner.Call(aggregate.Accumulate(), oldState.State, timestamp, input) }; Expression <Func <NullOutputWrapper <TState>, long, TInput, NullOutputWrapper <TState> > > newDeaccumulate = (oldState, timestamp, input) => new NullOutputWrapper <TState> { Count = oldState.Count - 1, State = CallInliner.Call(aggregate.Deaccumulate(), oldState.State, timestamp, input) }; Expression <Func <NullOutputWrapper <TState>, NullOutputWrapper <TState>, NullOutputWrapper <TState> > > newDifference = (leftState, rightState) => new NullOutputWrapper <TState> { Count = leftState.Count - rightState.Count, State = CallInliner.Call(aggregate.Difference(), leftState.State, rightState.State) }; Expression <Func <NullOutputWrapper <TState>, TResult> > newComputeResult = state => state.Count == 0 ? default : CallInliner.Call(aggregate.ComputeResult(), state.State); return(GeneratedAggregate.Create( initialState: newInitialState.InlineCalls(), accumulate: newAccumulate.InlineCalls(), deaccumulate: newDeaccumulate.InlineCalls(), difference: newDifference.InlineCalls(), computeResult: newComputeResult.InlineCalls())); }
public static IAggregate <TInput, TState, TResult> ApplyFilter <TInput, TState, TResult>( this IAggregate <TInput, TState, TResult> aggregate, Expression <Func <TInput, bool> > filter) { Contract.Requires(aggregate != null); if (filter == null || filter.Body.ExpressionEquals(Expression.Constant(true))) { return(aggregate); } Expression <Func <TState, long, TInput, TState> > newAccumulate = (oldState, timestamp, input) => CallInliner.Call(filter, input) ? CallInliner.Call(aggregate.Accumulate(), oldState, timestamp, input) : oldState; Expression <Func <TState, long, TInput, TState> > newDeaccumulate = (oldState, timestamp, input) => CallInliner.Call(filter, input) ? CallInliner.Call(aggregate.Deaccumulate(), oldState, timestamp, input) : oldState; return(GeneratedAggregate.Create( initialState: aggregate.InitialState(), accumulate: newAccumulate.InlineCalls(), deaccumulate: newDeaccumulate.InlineCalls(), difference: aggregate.Difference(), computeResult: aggregate.ComputeResult())); }
public static IAggregate <TInput?, TState, TResult> MakeInputNullableAndSkipNulls <TInput, TState, TResult>( this IAggregate <TInput, TState, TResult> aggregate) where TInput : struct { Contract.Requires(aggregate != null); Expression <Func <TState, long, TInput?, TState> > newAccumulate = (oldState, timestamp, input) => input.HasValue ? CallInliner.Call(aggregate.Accumulate(), oldState, timestamp, input.Value) : oldState; Expression <Func <TState, long, TInput?, TState> > newDeaccumulate = (oldState, timestamp, input) => input.HasValue ? CallInliner.Call(aggregate.Deaccumulate(), oldState, timestamp, input.Value) : oldState; return(GeneratedAggregate.Create( initialState: aggregate.InitialState(), accumulate: newAccumulate.InlineCalls(), deaccumulate: newDeaccumulate.InlineCalls(), difference: aggregate.Difference(), computeResult: aggregate.ComputeResult())); }