示例#1
0
        public PartitionedLeftAntiSemiJoinPipe(LeftAntiSemiJoinStreamable <TKey, TLeft, TRight> stream, IStreamObserver <TKey, TLeft> observer)
            : base(stream, observer)
        {
            this.keyComparer       = stream.Properties.KeyEqualityComparer.GetEqualsExpr();
            this.keyComparerEquals = this.keyComparer.Compile();

            this.leftComparer       = stream.LeftComparer.GetEqualsExpr();
            this.leftComparerEquals = this.leftComparer.Compile();

            if (stream.Left.Properties.IsConstantDuration)
            {
                this.leftEndPointGenerator = () => new EndPointQueue();
            }
            else
            {
                this.leftEndPointGenerator = () => new EndPointHeap();
            }
            if (stream.Right.Properties.IsConstantDuration)
            {
                this.rightEndPointGenerator = () => new EndPointQueue();
            }
            else
            {
                this.rightEndPointGenerator = () => new EndPointHeap();
            }

            this.pool = MemoryManager.GetMemoryPool <TKey, TLeft>(stream.Properties.IsColumnar);
            this.pool.Get(out this.output);
            this.output.Allocate();
        }
示例#2
0
        /// <summary>
        /// Generate a batch class definition to be used as a Clip pipe.
        /// Compile the definition, dynamically load the assembly containing it, and return the Type representing the
        /// aggregate class.
        /// </summary>
        /// <typeparam name="TKey">The key type for both sides.</typeparam>
        /// <typeparam name="TLeft">The payload type for the left side.</typeparam>
        /// <typeparam name="TRight">The payload type for the right side.</typeparam>
        /// <returns>
        /// A type that is defined to be a subtype of BinaryPipe&lt;<typeparamref name="TKey"/>,<typeparamref name="TLeft"/>, <typeparamref name="TKey"/>, <typeparamref name="TRight"/>&gt;.
        /// </returns>
        internal static Tuple <Type, string> Generate <TKey, TLeft, TRight>(LeftAntiSemiJoinStreamable <TKey, TLeft, TRight> stream, bool leftIsConstantDuration)
        {
            Contract.Requires(stream != null);
            Contract.Ensures(Contract.Result <Tuple <Type, string> >() == null || typeof(BinaryPipe <TKey, TLeft, TRight, TLeft>).GetTypeInfo().IsAssignableFrom(Contract.Result <Tuple <Type, string> >().Item1));

            var template = new LeftAntiSemiJoinTemplate($"GeneratedLeftAntiSemiJoin_{LASJSequenceNumber++}", typeof(TKey), typeof(TLeft), typeof(TRight));

            var gps = template.tm.GenericTypeVariables(template.keyType, template.leftType, template.rightType);

            template.genericParameters = gps.BracketedCommaSeparatedString();

            var leftMessageRepresentation = new ColumnarRepresentation(template.leftType);
            var resultRepresentation      = new ColumnarRepresentation(template.leftType);

            #region Key Comparer
            var keyComparer = stream.Properties.KeyEqualityComparer.GetEqualsExpr();
            template.keyComparer =
                (left, right) =>
                keyComparer.Inline(left, right);
            #endregion

            #region Left Comparer
            template.ActiveEventType        = template.leftType.GetTypeInfo().IsValueType ? template.TLeft : "Active_Event";
            template.noLeftFields           = leftMessageRepresentation.noFields;
            template.leftIsConstantDuration = leftIsConstantDuration;

            var leftComparer = stream.LeftComparer.GetEqualsExpr();
            var newLambda    = Extensions.TransformFunction <TKey, TLeft>(leftComparer, "index");
            template.leftComparer = (left, right) => newLambda.Inline(left, right);
            #endregion

            template.BatchGeneratedFrom_TKey_TLeft = Transformer.GetBatchClassName(template.keyType, template.leftType);
            template.TKeyTLeftGenericParameters    = template.tm.GenericTypeVariables(template.keyType, template.leftType).BracketedCommaSeparatedString();

            template.BatchGeneratedFrom_TKey_TRight = Transformer.GetBatchClassName(template.keyType, template.rightType);
            template.TKeyTRightGenericParameters    = template.tm.GenericTypeVariables(template.keyType, template.rightType).BracketedCommaSeparatedString();

            template.leftFields = resultRepresentation.AllFields;

            return(template.Generate <TKey, TLeft, TRight>(leftComparer));
        }
示例#3
0
        /// <summary>
        /// Generate a batch class definition to be used as a Clip pipe.
        /// Compile the definition, dynamically load the assembly containing it, and return the Type representing the
        /// aggregate class.
        /// </summary>
        /// <typeparam name="TKey">The key type for both sides.</typeparam>
        /// <typeparam name="TLeft">The payload type for the left side.</typeparam>
        /// <typeparam name="TRight">The payload type for the right side.</typeparam>
        /// <returns>
        /// A type that is defined to be a subtype of BinaryPipe&lt;<typeparamref name="TKey"/>,<typeparamref name="TLeft"/>, <typeparamref name="TKey"/>, <typeparamref name="TRight"/>&gt;.
        /// </returns>
        internal static Tuple <Type, string> Generate <TKey, TLeft, TRight>(LeftAntiSemiJoinStreamable <TKey, TLeft, TRight> stream, bool leftIsConstantDuration)
        {
            Contract.Requires(stream != null);
            Contract.Ensures(Contract.Result <Tuple <Type, string> >() == null || typeof(BinaryPipe <TKey, TLeft, TRight, TLeft>).GetTypeInfo().IsAssignableFrom(Contract.Result <Tuple <Type, string> >().Item1));

            string errorMessages = null;

            try
            {
                var template = new LeftAntiSemiJoinTemplate();

                var keyType   = template.keyType = typeof(TKey);
                var leftType  = template.leftType = typeof(TLeft);
                var rightType = template.rightType = typeof(TRight);

                var tm = new TypeMapper(keyType, leftType, rightType);
                template.TKey   = tm.CSharpNameFor(keyType);
                template.TLeft  = tm.CSharpNameFor(leftType);
                template.TRight = tm.CSharpNameFor(rightType);
                var gps = tm.GenericTypeVariables(keyType, leftType, rightType);
                template.genericParameters = gps.BracketedCommaSeparatedString();

                template.className = string.Format("GeneratedLeftAntiSemiJoin_{0}", LASJSequenceNumber++);

                var leftMessageRepresentation = new ColumnarRepresentation(leftType);
                var resultRepresentation      = new ColumnarRepresentation(leftType);

                #region Key Comparer
                var keyComparer = stream.Properties.KeyEqualityComparer.GetEqualsExpr();
                template.keyComparer =
                    (left, right) =>
                    keyComparer.Inline(left, right);
                #endregion

                #region Left Comparer
                template.ActiveEventType        = leftType.GetTypeInfo().IsValueType ? template.TLeft : "Active_Event";
                template.noLeftFields           = leftMessageRepresentation.noFields;
                template.leftIsConstantDuration = leftIsConstantDuration;

                var leftComparer = stream.LeftComparer.GetEqualsExpr();
                var newLambda    = Extensions.TransformFunction <TKey, TLeft>(leftComparer, "index");
                template.leftComparer = (left, right) => newLambda.Inline(left, right);
                #endregion

                template.BatchGeneratedFrom_TKey_TLeft = Transformer.GetBatchClassName(keyType, leftType);
                template.TKeyTLeftGenericParameters    = tm.GenericTypeVariables(keyType, leftType).BracketedCommaSeparatedString();

                template.BatchGeneratedFrom_TKey_TRight = Transformer.GetBatchClassName(keyType, rightType);
                template.TKeyTRightGenericParameters    = tm.GenericTypeVariables(keyType, rightType).BracketedCommaSeparatedString();

                template.leftFields = resultRepresentation.AllFields;

                template.staticCtor = Transformer.StaticCtor(template.className);
                var expandedCode = template.TransformText();

                var assemblyReferences = Transformer.AssemblyReferencesNeededFor(typeof(TKey), typeof(TLeft), typeof(TRight));
                assemblyReferences.Add(typeof(IStreamable <,>).GetTypeInfo().Assembly);
                assemblyReferences.Add(Transformer.GeneratedStreamMessageAssembly <TKey, TLeft>());
                assemblyReferences.Add(Transformer.GeneratedStreamMessageAssembly <TKey, TRight>());
                assemblyReferences.AddRange(Transformer.AssemblyReferencesNeededFor(leftComparer));

                var a             = Transformer.CompileSourceCode(expandedCode, assemblyReferences, out errorMessages);
                var realClassName = template.className.AddNumberOfNecessaryGenericArguments(keyType, leftType, rightType);
                var t             = a.GetType(realClassName);
                if (t.GetTypeInfo().IsGenericType)
                {
                    var list = keyType.GetAnonymousTypes();
                    list.AddRange(leftType.GetAnonymousTypes());
                    list.AddRange(rightType.GetAnonymousTypes());
                    return(Tuple.Create(t.MakeGenericType(list.ToArray()), errorMessages));
                }
                else
                {
                    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));
            }
        }