예제 #1
0
        protected override bool CanGenerateColumnar()
        {
            var typeOfTKey   = typeof(TKey);
            var typeOfTLeft  = typeof(TLeft);
            var typeOfTRight = typeof(TRight);

            if (!typeOfTLeft.CanRepresentAsColumnar())
            {
                return(false);
            }
            if (!typeOfTRight.CanRepresentAsColumnar())
            {
                return(false);
            }
            if (typeOfTKey.GetPartitionType() != null)
            {
                return(false);
            }

            var lookupKey = CacheKey.Create(this.Properties.KeyEqualityComparer.GetEqualsExpr().ToString(), this.LeftComparer.GetEqualsExpr().ToString());

            var generatedPipeType = cachedPipes.GetOrAdd(lookupKey, key => ClipJoinTemplate.Generate(this));

            this.errorMessages = generatedPipeType.Item2;
            return(generatedPipeType.Item1 != null);
        }
예제 #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>(ClipJoinStreamable <TKey, TLeft, TRight> stream)
        {
            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 ClipJoinTemplate($"GeneratedClip_{ClipSequenceNumber++}", typeof(TKey), typeof(TLeft), typeof(TRight));

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

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

            template.genericParameters = gps.BracketedCommaSeparatedString();

            var resultRepresentation = new ColumnarRepresentation(leftType);

            template.ActiveEventType = leftType.GetTypeInfo().IsValueType ? template.TLeft : "Active_Event";

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

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

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

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

            template.leftFields = resultRepresentation.AllFields;
            template.noFields   = resultRepresentation.noFields;

            return(template.Generate <TKey, TLeft, TRight>(leftComparer));
        }
예제 #3
0
        private BinaryPipe <TKey, TLeft, TRight, TLeft> GetPipe(IStreamObserver <TKey, TLeft> observer)
        {
            var lookupKey = CacheKey.Create(this.Properties.KeyEqualityComparer.GetEqualsExpr().ToString(), this.LeftComparer.GetEqualsExpr().ToString());

            var generatedPipeType = cachedPipes.GetOrAdd(lookupKey, key => ClipJoinTemplate.Generate(this));
            Func <PlanNode, PlanNode, IBinaryObserver, BinaryPlanNode> planNode = ((PlanNode left, PlanNode right, IBinaryObserver o) =>
            {
                var node = new JoinPlanNode(
                    left, right, o,
                    typeof(TLeft), typeof(TRight), typeof(TLeft), typeof(TKey),
                    JoinKind.Clip, true, generatedPipeType.Item2, false);
                node.AddJoinExpression("left comparer", this.LeftComparer.GetEqualsExpr());
                node.AddJoinExpression("key comparer", this.Properties.KeyComparer.GetCompareExpr());
                return(node);
            });

            var instance    = Activator.CreateInstance(generatedPipeType.Item1, this, observer, this.Properties.KeyEqualityComparer, this.LeftComparer, planNode);
            var returnValue = (BinaryPipe <TKey, TLeft, TRight, TLeft>)instance;

            return(returnValue);
        }