/// <summary> /// Generate a batch class definition to be used as a Beat pipe. /// Compile the definition, dynamically load the assembly containing it, and return the Type representing the /// union pipe class. /// </summary> /// <typeparam name="TKey">The key type for both sides.</typeparam> /// <typeparam name="TPayload">The payload type.</typeparam> /// <returns> /// A type that is defined to be a subtype of UnaryPipe<<typeparamref name="TKey"/>,<typeparamref name="TPayload"/>, <typeparamref name="TPayload"/>>. /// </returns> internal static Tuple <Type, string> Generate <TKey, TPayload>(ExtendLifetimeStreamable <TKey, TPayload> stream, long duration) { Contract.Requires(stream != null); Contract.Ensures(Contract.Result <Tuple <Type, string> >() == null || typeof(UnaryPipe <TKey, TPayload, TPayload>).GetTypeInfo().IsAssignableFrom(Contract.Result <Tuple <Type, string> >().Item1)); var result = Generate(stream, duration, false, false); if (duration >= 0) { return(result); // only negative pipe uses comparers } if (result.Item1 != null) { return(result); } result = Generate(stream, duration, true, false); if (result.Item1 != null) { return(result); } result = Generate(stream, duration, true, true); return(result); }
public ExtendLifetimePipe(ExtendLifetimeStreamable <TKey, TPayload> stream, IStreamObserver <TKey, TPayload> observer, long duration) : base(stream, observer) { this.duration = duration; this.pool = MemoryManager.GetMemoryPool <TKey, TPayload>(stream.Properties.IsColumnar); this.errorMessages = stream.ErrorMessages; this.pool.Get(out this.output); this.output.Allocate(); }
internal static Tuple <Type, string> Generate <TKey, TPayload>(ExtendLifetimeStreamable <TKey, TPayload> stream, long duration, bool useCompiledKeyComparer, bool useCompiledPayloadComparer) { Contract.Requires(stream != null); Contract.Ensures(Contract.Result <Tuple <Type, string> >() == null || typeof(UnaryPipe <TKey, TPayload, TPayload>).GetTypeInfo().IsAssignableFrom(Contract.Result <Tuple <Type, string> >().Item1)); #if CODEGEN_TIMING Stopwatch sw = new Stopwatch(); sw.Start(); #endif ExtendLifetimeBaseTemplate template; var className = string.Format("GeneratedExtendLifetime_{0}", ExtendLifetimeSequenceNumber++); if (duration < 0) { template = new ExtendLifetimeNegativeTemplate(className, typeof(TKey), typeof(TPayload)); } else { template = new ExtendLifetimeTemplate(className, typeof(TKey), typeof(TPayload)); } template.ActiveEventType = typeof(TPayload).GetTypeInfo().IsValueType ? template.TPayload : "Active_Event"; #region Key Comparer template.useCompiledKeyComparer = useCompiledKeyComparer; if (useCompiledKeyComparer) { template.keyComparer = (left, right) => string.Format("keyComparer({0}, {1}", left, right); } else { var keyComparer = stream.Properties.KeyEqualityComparer.GetEqualsExpr(); template.keyComparer = (left, right) => keyComparer.Inline(left, right); } #endregion #region Payload Comparer template.useCompiledPayloadComparer = useCompiledPayloadComparer; if (useCompiledPayloadComparer) { template.payloadComparer = (left, right) => string.Format("payloadComparer({0}.Payload, {1}.Payload", left, right); } else { var payloadComparer = stream.Properties.PayloadEqualityComparer.GetEqualsExpr(); var newLambda = Extensions.TransformFunction <TKey, TPayload>(payloadComparer, "index"); template.payloadComparer = (left, right) => newLambda.Inline(left, right); } #endregion return(template.Generate <TKey, TPayload>(typeof(IStreamable <,>))); }
private UnaryPipe <TKey, TPayload, TPayload> GetPipe(ExtendLifetimeStreamable <TKey, TPayload> stream, IStreamObserver <TKey, TPayload> observer) { var lookupKey = CacheKey.Create(this.duration); var generatedPipeType = cachedPipes.GetOrAdd(lookupKey, key => ExtendLifetimeBaseTemplate.Generate(stream, this.duration)); Func <PlanNode, IQueryObject, PlanNode> planNode = (PlanNode p, IQueryObject o) => new ExtendLifetimePlanNode(p, o, typeof(TKey), typeof(TPayload), true, generatedPipeType.Item2, this.duration < 0); var instance = Activator.CreateInstance(generatedPipeType.Item1, stream, observer, planNode, (this.duration < 0) ? -this.duration : this.duration); var returnValue = (UnaryPipe <TKey, TPayload, TPayload>)instance; return(returnValue); }
public ExtendLifetimeNegativePipe(ExtendLifetimeStreamable <TKey, TPayload> stream, IStreamObserver <TKey, TPayload> observer, long duration) : base(stream, observer) { this.duration = duration; this.keyComparerExpr = stream.Properties.KeyEqualityComparer.GetEqualsExpr(); this.keyComparer = this.keyComparerExpr.Compile(); this.payloadComparerExpr = stream.Properties.PayloadEqualityComparer.GetEqualsExpr(); this.payloadComparer = this.payloadComparerExpr.Compile(); this.pool = MemoryManager.GetMemoryPool <TKey, TPayload>(stream.Properties.IsColumnar); this.errorMessages = stream.ErrorMessages; this.pool.Get(out this.output); this.output.Allocate(); }