private UnaryPipe <TKey, TPayload, TPayload> GetPipe(IStreamObserver <TKey, TPayload> observer) { var lookupKey = CacheKey.Create(this.Predicate.ExpressionToCSharp()); var generatedPipeType = cachedPipes.GetOrAdd(lookupKey, key => WhereTemplate.Generate(this)); Func <PlanNode, IQueryObject, PlanNode> planNode = ((PlanNode p, IQueryObject o) => new WherePlanNode(p, o, typeof(TKey), typeof(TPayload), this.Predicate, true, generatedPipeType.Item2)); var instance = Activator.CreateInstance(generatedPipeType.Item1, this, observer, planNode); var returnValue = (UnaryPipe <TKey, TPayload, TPayload>)instance; return(returnValue); }
protected override bool CanGenerateColumnar() { var typeOfTKey = typeof(TKey); var typeOfTSource = typeof(TPayload); if (!typeOfTSource.CanRepresentAsColumnar()) { return(false); } if (typeOfTKey.GetPartitionType() != null) { return(false); } var lookupKey = CacheKey.Create(this.Predicate.ExpressionToCSharp()); var generatedPipeType = cachedPipes.GetOrAdd(lookupKey, key => WhereTemplate.Generate(this)); this.errorMessages = generatedPipeType.Item2; return(generatedPipeType.Item1 != null); }
internal static Tuple <Type, string> Generate <TKey, TPayload>(WhereStreamable <TKey, TPayload> stream) { string generatedClassName; string expandedCode; var assemblyReferences = new List <Assembly>(); string errorMessages = null; try { var keyType = typeof(TKey); assemblyReferences.AddRange(Transformer.AssemblyReferencesNeededFor(keyType)); var sourceType = typeof(TPayload); assemblyReferences.AddRange(Transformer.AssemblyReferencesNeededFor(sourceType)); assemblyReferences.AddRange(Transformer.AssemblyReferencesNeededFor(stream.Predicate)); generatedClassName = string.Format("WhereUnaryPipeGeneratedFrom_{0}_{1}_{2}", keyType.GetValidIdentifier(), sourceType.GetValidIdentifier(), sequenceNumber++); var noTransformation = false; var p = stream.Predicate.Body; var transformedPredicate = p; var multiStringInit = string.Empty; var multiStringReturns = string.Empty; var multiStringWrapperInit = string.Empty; string vectorOperations = null; if (Config.UseMultiString && Config.MultiStringTransforms != Config.CodegenOptions.MultiStringFlags.None) { var result = MultiStringTransformer.Transform(sourceType, transformedPredicate); if (result.transformedExpression != null) { transformedPredicate = result.transformedExpression; } multiStringInit = string.Join("\n", result.wrapperTable.Select(e => string.Format( "var {0} = new MultiString.MultiStringWrapper({1}{2}_col);", e.Value.Name, Transformer.ColumnFieldPrefix, e.Key.Name))); multiStringWrapperInit = string.Join("\n", result.wrapperTable.Select(e => string.Format("{0}.rowIndex = i;", e.Value.Name))); vectorOperations = result.vectorOperation; } Contract.Assume(stream.Predicate.Parameters.Count() == 1); var parameter = stream.Predicate.Parameters.First(); var x = Extensions.TransformUnaryFunction <TKey, TPayload>(Expression.Lambda(transformedPredicate, parameter)); noTransformation = x == null; transformedPredicate = noTransformation ? p : x.Body; var template = new WhereTemplate( generatedClassName, keyType, sourceType, transformedPredicate.ExpressionToCSharp(), noTransformation, stream.Predicate.Parameters[0].ToString(), multiStringInit, multiStringReturns) { multiStringWrapperInit = multiStringWrapperInit, vectorOperations = vectorOperations }; generatedClassName = generatedClassName.AddNumberOfNecessaryGenericArguments(keyType, sourceType); expandedCode = template.TransformText(); assemblyReferences.Add(Transformer.GeneratedStreamMessageAssembly <TKey, TPayload>()); assemblyReferences.Add(typeof(IStreamable <,>).GetTypeInfo().Assembly); var a = Transformer.CompileSourceCode(expandedCode, assemblyReferences, out errorMessages); var t = a.GetType(generatedClassName); t = t.InstantiateAsNecessary(typeof(TKey), typeof(TPayload)); return(Tuple.Create(t, errorMessages)); } catch { if (Config.CodegenOptions.DontFallBackToRowBasedExecution) { throw new InvalidOperationException("Code Generation failed when it wasn't supposed to!"); } return(Tuple.Create((Type)null, errorMessages)); } }