コード例 #1
0
        internal static Tuple <Type, string> GenerateAFA <TKey, TPayload, TRegister, TAccumulator>(
            AfaStreamable <TKey, TPayload, TRegister, TAccumulator> stream)
        {
            Contract.Requires(stream != null);
            Contract.Ensures(Contract.Result <Tuple <Type, string> >() == null || typeof(UnaryPipe <TKey, TPayload, TRegister>).GetTypeInfo().IsAssignableFrom(Contract.Result <Tuple <Type, string> >().Item1));

            var className = $"GeneratedUngroupedDAfa_{AFASequenceNumber++}";
            var template  = new UngroupedDAfaTemplate(className, typeof(TPayload), typeof(TRegister), typeof(TAccumulator))
            {
                isFinal                    = stream.afa.isFinal,
                hasOutgoingArcs            = stream.afa.hasOutgoingArcs,
                startStates                = stream.afa.startStates,
                AllowOverlappingInstances  = stream.afa.uncompiledAfa.AllowOverlappingInstances,
                isSyncTimeSimultaneityFree = stream.Properties.IsSyncTimeSimultaneityFree,
            };

            var d1          = stream.afa.uncompiledAfa.transitionInfo;
            var orderedKeys = d1.Keys.OrderBy(e => e).ToArray();

            for (int i = 0; i < orderedKeys.Length; i++)
            {
                var sourceNodeNumber        = orderedKeys[i];
                var outgoingEdgesDictionary = d1[sourceNodeNumber];
                var orderedTargetNodes      = outgoingEdgesDictionary.Keys.OrderBy(e => e).ToArray();
                var edgeList1 = new List <EdgeInfo>();
                for (int j = 0; j < orderedTargetNodes.Length; j++)
                {
                    var targetNodeNumber = orderedTargetNodes[j];
                    var edge             = outgoingEdgesDictionary[targetNodeNumber];
                    if (edge is SingleElementArc <TPayload, TRegister> searc)
                    {
                        var edgeInfo = CreateSingleEdgeInfo(stream, targetNodeNumber, searc, "i");
                        edgeList1.Add(edgeInfo);
                    }
                }
                template.currentlyActiveInfo.Add(Tuple.Create(sourceNodeNumber, edgeList1));
            }
            for (int i = 0; i < stream.afa.startStates.Length; i++)
            {
                var startState             = stream.afa.startStates[i];
                var edgeList2              = new List <EdgeInfo>();
                var outgoingEdgeDictionary = stream.afa.uncompiledAfa.transitionInfo[startState];
                foreach (var edge in outgoingEdgeDictionary)
                {
                    var targetNode = edge.Key;
                    var arc        = edge.Value;
                    if (arc is SingleElementArc <TPayload, TRegister> searc)
                    {
                        var edgeInfo = CreateSingleEdgeInfo(stream, targetNode, searc, "i");
                        edgeList2.Add(edgeInfo);
                    }
                }

                template.newActivationInfo.Add(Tuple.Create(startState, edgeList2));
            }

            return(template.Generate <TKey, TPayload, TRegister, TAccumulator>());
        }
コード例 #2
0
        public CompiledUngroupedAfaPipe(AfaStreamable <Empty, TPayload, TRegister, TAccumulator> stream, IStreamObserver <Empty, TRegister> observer, object afa, long maxDuration)
            : base(stream, observer, afa, maxDuration, false)
        {
            this.activeStates = new FastLinkedList <GroupedActiveState <Empty, TRegister> >();

            if (!this.IsSyncTimeSimultaneityFree)
            {
                this.seenEvent       = 0;
                this.tentativeOutput = new FastLinkedList <OutputEvent <Empty, TRegister> >();
                this.lastSyncTime    = -1;
            }
        }
コード例 #3
0
        public CompiledPartitionedAfaPipe_SingleEvent(AfaStreamable <TKey, TPayload, TRegister, TAccumulator> stream, IStreamObserver <TKey, TRegister> observer, object afa, long maxDuration)
            : base(stream, observer, afa, maxDuration, false)
        {
            this.getPartitionKey = GetPartitionExtractor <TPartitionKey, TKey>();
            this.activeStates    = new FastMap <GroupedActiveState <TKey, TRegister> >();

            if (!this.IsSyncTimeSimultaneityFree)
            {
                var comparer        = stream.Properties.KeyEqualityComparer;
                var equalsFunc      = comparer.GetEqualsExpr().Compile();
                var getHashCodeFunc = comparer.GetGetHashCodeExpr().Compile();
                this.seenEvent       = comparer.CreateFastDictionary2Generator <TKey, byte>(10, equalsFunc, getHashCodeFunc, stream.Properties.QueryContainer).Invoke();
                this.tentativeOutput = new FastDictionary2 <TPartitionKey, FastMap <OutputEvent <TKey, TRegister> > >();
            }
        }
コード例 #4
0
        internal static Tuple <Type, string> GenerateAFA <TKey, TPayload, TRegister, TAccumulator>(
            AfaStreamable <TKey, TPayload, TRegister, TAccumulator> stream)
        {
            Contract.Requires(stream != null);
            Contract.Ensures(Contract.Result <Tuple <Type, string> >() == null || typeof(UnaryPipe <TKey, TPayload, TRegister>).GetTypeInfo().IsAssignableFrom(Contract.Result <Tuple <Type, string> >().Item1));

            string errorMessages = null;

            try
            {
                var className             = string.Format("GeneratedGroupedAfaMultiEvent_{0}", AFASequenceNumber++);
                var template              = new GroupedAfaMultiEventTemplate(className, typeof(TKey), typeof(TPayload), typeof(TRegister), typeof(TAccumulator));
                var payloadRepresentation = new ColumnarRepresentation(typeof(TPayload));

                template.isFinal                   = stream.afa.isFinal;
                template.hasOutgoingArcs           = stream.afa.hasOutgoingArcs;
                template.startStates               = stream.afa.startStates;
                template.AllowOverlappingInstances = stream.afa.uncompiledAfa.AllowOverlappingInstances;

                var d1          = stream.afa.uncompiledAfa.transitionInfo;
                var orderedKeys = d1.Keys.OrderBy(e => e).ToArray();
                for (int i = 0; i < orderedKeys.Length; i++)
                {
                    var sourceNodeNumber        = orderedKeys[i];
                    var outgoingEdgesDictionary = d1[sourceNodeNumber];
                    var orderedTargetNodes      = outgoingEdgesDictionary.Keys.OrderBy(e => e).ToArray();
                    var edgeList = new List <MultiEdgeInfo>();
                    for (int j = 0; j < orderedTargetNodes.Length; j++)
                    {
                        var targetNodeNumber = orderedTargetNodes[j];
                        var edge             = outgoingEdgesDictionary[targetNodeNumber];
                        if (edge is MultiElementArc <TPayload, TRegister, TAccumulator> multiArc)
                        {
                            var multiEdgeInfo = new MultiEdgeInfo()
                            {
                                SourceNode            = sourceNodeNumber,
                                TargetNode            = targetNodeNumber,
                                fromStartState        = stream.afa.startStates.Any(n => n == sourceNodeNumber),
                                EpsilonReachableNodes = EpsilonClosure(stream.afa, targetNodeNumber),
                                Initialize            = (ts, reg) => multiArc.Initialize.Inline(ts, reg),
                                Accumulate            = (ts, ev, reg, acc) =>
                                {
                                    var transformedAccumulate = Extensions.TransformFunction <TKey, TPayload>(multiArc.Accumulate, 1, batchVariableName: "sourceBatch");
                                    return(transformedAccumulate.Inline(ts, reg, acc));
                                },
                                Fence = (ts, acc, reg) => multiArc.Fence.Inline(ts, acc, reg),
                            };
                            if (multiArc.Transfer == null)
                            {
                                multiEdgeInfo.Transfer = null;
                            }
                            else
                            {
                                multiEdgeInfo.Transfer = (ts, acc, reg) => multiArc.Transfer.Inline(ts, acc, reg);
                            }
                            if (multiArc.Dispose == null)
                            {
                                multiEdgeInfo.Dispose = (acc) => "// no dispose function";
                            }
                            else
                            {
                                multiEdgeInfo.Dispose = (acc) => multiArc.Dispose.Inline(acc);
                            }
                            if (multiArc.SkipToEnd == null)
                            {
                                multiEdgeInfo.SkipToEnd = null;
                            }
                            else
                            {
                                multiEdgeInfo.SkipToEnd = (ts, ev, acc) => multiArc.SkipToEnd.Inline(ts, ev, acc);
                            }

                            edgeList.Add(multiEdgeInfo);
                        }
                    }
                    template.edgeInfos.Add(Tuple.Create(sourceNodeNumber, edgeList));
                }
                for (int i = 0; i < stream.afa.startStates.Length; i++)
                {
                    var startState             = stream.afa.startStates[i];
                    var edgeList2              = new List <MultiEdgeInfo>();
                    var outgoingEdgeDictionary = stream.afa.uncompiledAfa.transitionInfo[startState];
                    foreach (var edge in outgoingEdgeDictionary)
                    {
                        var targetNode = edge.Key;
                        var arc        = edge.Value;
                        if (arc is MultiElementArc <TPayload, TRegister, TAccumulator> multiArc)
                        {
                            var eps = EpsilonClosure(stream.afa, targetNode);

                            var multiEdgeInfo = new MultiEdgeInfo()
                            {
                                SourceNode            = startState,
                                TargetNode            = targetNode,
                                fromStartState        = true,
                                EpsilonReachableNodes = EpsilonClosure(stream.afa, targetNode),
                                Initialize            = (ts, reg) => multiArc.Initialize.Inline(ts, reg),
                                Accumulate            = (ts, ev, reg, acc) =>
                                {
                                    var transformedAccumulate = Extensions.TransformFunction <TKey, TPayload>(multiArc.Accumulate, 1, batchVariableName: "sourceBatch");
                                    return(transformedAccumulate.Inline(ts, reg, acc));
                                },
                                Fence = (ts, acc, reg) => multiArc.Fence.Inline(ts, acc, reg),
                            };
                            if (multiArc.Transfer == null)
                            {
                                multiEdgeInfo.Transfer = null;
                            }
                            else
                            {
                                multiEdgeInfo.Transfer = (ts, acc, reg) => multiArc.Transfer.Inline(ts, acc, reg);
                            }
                            if (multiArc.Dispose == null)
                            {
                                multiEdgeInfo.Dispose = (acc) => "// no dispose function";
                            }
                            else
                            {
                                multiEdgeInfo.Dispose = (acc) => multiArc.Dispose.Inline(acc);
                            }
                            if (multiArc.SkipToEnd == null)
                            {
                                multiEdgeInfo.SkipToEnd = null;
                            }
                            else
                            {
                                multiEdgeInfo.SkipToEnd = (ts, ev, acc) => multiArc.SkipToEnd.Inline(ts, ev, acc);
                            }
                            edgeList2.Add(multiEdgeInfo);
                        }
                    }

                    template.startEdgeInfos.Add(Tuple.Create(startState, edgeList2));
                }

                template.isSyncTimeSimultaneityFree = true; // The handwritten version doesn't make a distinction.
                template.keyEqualityComparer        =
                    (left, right) =>
                    stream.Properties.KeyEqualityComparer.GetEqualsExpr().Inline(left, right);

                var expandedCode = template.TransformText();

                var assemblyReferences = Transformer.AssemblyReferencesNeededFor(typeof(TKey), typeof(TPayload), typeof(TRegister));
                assemblyReferences.Add(typeof(IStreamable <,>).GetTypeInfo().Assembly);
                assemblyReferences.Add(Transformer.GeneratedStreamMessageAssembly <TKey, TPayload>());
                assemblyReferences.Add(Transformer.GeneratedStreamMessageAssembly <TKey, TRegister>());
                assemblyReferences.Add(Transformer.GeneratedMemoryPoolAssembly <TKey, TRegister>());

                var a = Transformer.CompileSourceCode(expandedCode, assemblyReferences, out errorMessages);
                var t = a.GetType(template.className);
                if (t.GetTypeInfo().IsGenericType)
                {
                    var list = typeof(TKey).GetAnonymousTypes();
                    list.AddRange(template.payloadType.GetAnonymousTypes());
                    list.AddRange(template.registerType.GetAnonymousTypes());
                    t = t.MakeGenericType(list.ToArray());
                }
                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));
            }
        }
コード例 #5
0
        internal static Tuple <Type, string> GenerateAFA <TKey, TPayload, TRegister, TAccumulator>(
            AfaStreamable <TKey, TPayload, TRegister, TAccumulator> stream)
        {
            Contract.Requires(stream != null);
            Contract.Ensures(Contract.Result <Tuple <Type, string> >() == null || typeof(UnaryPipe <TKey, TPayload, TRegister>).GetTypeInfo().IsAssignableFrom(Contract.Result <Tuple <Type, string> >().Item1));

            string errorMessages = null;

            try
            {
                var className = string.Format("GeneratedUngroupedDAfa_{0}", AFASequenceNumber++);
                var template  = new UngroupedDAfaTemplate(className, typeof(TKey), typeof(TPayload), typeof(TRegister), typeof(TAccumulator))
                {
                    TKey = typeof(TKey).GetCSharpSourceSyntax()
                };

                template.isFinal                   = stream.afa.isFinal;
                template.hasOutgoingArcs           = stream.afa.hasOutgoingArcs;
                template.startStates               = stream.afa.startStates;
                template.AllowOverlappingInstances = stream.afa.uncompiledAfa.AllowOverlappingInstances;

                var d1          = stream.afa.uncompiledAfa.transitionInfo;
                var orderedKeys = d1.Keys.OrderBy(e => e).ToArray();
                for (int i = 0; i < orderedKeys.Length; i++)
                {
                    var sourceNodeNumber        = orderedKeys[i];
                    var outgoingEdgesDictionary = d1[sourceNodeNumber];
                    var orderedTargetNodes      = outgoingEdgesDictionary.Keys.OrderBy(e => e).ToArray();
                    var edgeList1 = new List <EdgeInfo>();
                    for (int j = 0; j < orderedTargetNodes.Length; j++)
                    {
                        var targetNodeNumber = orderedTargetNodes[j];
                        var edge             = outgoingEdgesDictionary[targetNodeNumber];
                        if (edge is SingleElementArc <TPayload, TRegister> searc)
                        {
                            var edgeInfo = CreateSingleEdgeInfo(stream, targetNodeNumber, searc, "i");
                            edgeList1.Add(edgeInfo);
                        }
                    }
                    template.currentlyActiveInfo.Add(Tuple.Create(sourceNodeNumber, edgeList1));
                }
                for (int i = 0; i < stream.afa.startStates.Length; i++)
                {
                    var startState             = stream.afa.startStates[i];
                    var edgeList2              = new List <EdgeInfo>();
                    var outgoingEdgeDictionary = stream.afa.uncompiledAfa.transitionInfo[startState];
                    foreach (var edge in outgoingEdgeDictionary)
                    {
                        var targetNode = edge.Key;
                        var arc        = edge.Value;
                        if (arc is SingleElementArc <TPayload, TRegister> searc)
                        {
                            var edgeInfo = CreateSingleEdgeInfo(stream, targetNode, searc, "i");
                            edgeList2.Add(edgeInfo);
                        }
                    }

                    template.newActivationInfo.Add(Tuple.Create(startState, edgeList2));
                }
                template.isSyncTimeSimultaneityFree = stream.Properties.IsSyncTimeSimultaneityFree;
                template.keyEqualityComparer        =
                    (left, right) =>
                    stream.Properties.KeyEqualityComparer.GetEqualsExpr().Inline(left, right);

                var expandedCode = template.TransformText();

                var assemblyReferences = Transformer.AssemblyReferencesNeededFor(typeof(TKey), typeof(TPayload), typeof(TRegister), typeof(Stack <>));
                assemblyReferences.Add(typeof(IStreamable <,>).GetTypeInfo().Assembly);
                assemblyReferences.Add(Transformer.GeneratedStreamMessageAssembly <TKey, TPayload>());
                assemblyReferences.Add(Transformer.GeneratedStreamMessageAssembly <TKey, TRegister>());
                assemblyReferences.Add(Transformer.GeneratedMemoryPoolAssembly <TKey, TRegister>());

                var a = Transformer.CompileSourceCode(expandedCode, assemblyReferences, out errorMessages);
                var t = a.GetType(template.className);
                if (t.GetTypeInfo().IsGenericType)
                {
                    var list = typeof(TKey).GetAnonymousTypes();
                    list.AddRange(template.payloadType.GetAnonymousTypes());
                    list.AddRange(template.registerType.GetAnonymousTypes());
                    t = t.MakeGenericType(list.ToArray());
                }
                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));
            }
        }
コード例 #6
0
        protected static EdgeInfo CreateListEdgeInfo <TKey, TPayload, TRegister, TAccumulator>(AfaStreamable <TKey, TPayload, TRegister, TAccumulator> stream, int targetNodeNumber, ListElementArc <TPayload, TRegister> edge)
        {
            var edgeInfo = new EdgeInfo()
            {
                Type = EdgeInfo.EdgeType.List,
                EpsilonReachableNodes = EpsilonClosure(stream.afa, targetNodeNumber),
                SourceNode            = targetNodeNumber,
                Fence    = (ts, evs, reg) => edge.Fence.Inline(ts, evs, reg),
                Transfer = edge.Transfer == null ? ((Func <string, string, string, string>)null) : (ts, evs, reg) => edge.Transfer.Inline(ts, evs, reg),
            };

            return(edgeInfo);
        }
コード例 #7
0
        protected static EdgeInfo CreateSingleEdgeInfo <TKey, TPayload, TRegister, TAccumulator>(AfaStreamable <TKey, TPayload, TRegister, TAccumulator> stream, int targetNodeNumber, SingleElementArc <TPayload, TRegister> searc)
        {
            var edgeInfo = new EdgeInfo()
            {
                Type = EdgeInfo.EdgeType.Single,
                EpsilonReachableNodes = EpsilonClosure(stream.afa, targetNodeNumber),
                SourceNode            = targetNodeNumber,
                Fence = (ts, ev, reg) => searc.Fence.Inline(ts, ev, reg),
            };

            edgeInfo.Transfer = searc.Transfer == null
                ? (Func <string, string, string, string>)null
                : ((ts, ev, reg) => searc.Transfer.Inline(ts, ev, reg));
            return(edgeInfo);
        }
コード例 #8
0
        internal static Tuple <Type, string> GenerateAFA <TKey, TPayload, TRegister, TAccumulator>(
            AfaStreamable <TKey, TPayload, TRegister, TAccumulator> stream)
        {
            Contract.Requires(stream != null);
            Contract.Ensures(Contract.Result <Tuple <Type, string> >() == null || typeof(UnaryPipe <TKey, TPayload, TRegister>).GetTypeInfo().IsAssignableFrom(Contract.Result <Tuple <Type, string> >().Item1));

            var className = $"GeneratedGroupedAfaEventList_{AFASequenceNumber++}";
            var template  = new GroupedAfaEventListTemplate(className, typeof(TKey), typeof(TPayload), typeof(TRegister), typeof(TAccumulator))
            {
                TKey                       = typeof(TKey).GetCSharpSourceSyntax(),
                isFinal                    = stream.afa.isFinal,
                hasOutgoingArcs            = stream.afa.hasOutgoingArcs,
                startStates                = stream.afa.startStates,
                AllowOverlappingInstances  = stream.afa.uncompiledAfa.AllowOverlappingInstances,
                isSyncTimeSimultaneityFree = true, // The handwritten version doesn't make a distinction.
                keyEqualityComparer        =
                    (left, right) =>
                    stream.Properties.KeyEqualityComparer.GetEqualsExpr().Inline(left, right),
            };

            var d1          = stream.afa.uncompiledAfa.transitionInfo;
            var orderedKeys = d1.Keys.OrderBy(e => e).ToArray();

            for (int i = 0; i < orderedKeys.Length; i++)
            {
                var sourceNodeNumber        = orderedKeys[i];
                var outgoingEdgesDictionary = d1[sourceNodeNumber];
                var orderedTargetNodes      = outgoingEdgesDictionary.Keys.OrderBy(e => e).ToArray();
                var edgeList1 = new List <EdgeInfo>();
                for (int j = 0; j < orderedTargetNodes.Length; j++)
                {
                    var targetNodeNumber = orderedTargetNodes[j];
                    var edge             = outgoingEdgesDictionary[targetNodeNumber];
                    if (edge is ListElementArc <TPayload, TRegister> leArc)
                    {
                        var edgeInfo = new EdgeInfo()
                        {
                            Type = EdgeInfo.EdgeType.List,
                            EpsilonReachableNodes = EpsilonClosure(stream.afa, targetNodeNumber),
                            Fence    = (ts, evs, reg) => leArc.Fence.Inline(ts, evs, reg),
                            Transfer = leArc.Transfer == null ? ((Func <string, string, string, string>)null) : (ts, evs, reg) => leArc.Transfer.Inline(ts, evs, reg),
                        };
                        edgeList1.Add(edgeInfo);
                    }
                }
                template.currentlyActiveInfo.Add(Tuple.Create(sourceNodeNumber, edgeList1));
            }
            for (int i = 0; i < stream.afa.startStates.Length; i++)
            {
                var startState             = stream.afa.startStates[i];
                var edgeList2              = new List <EdgeInfo>();
                var outgoingEdgeDictionary = stream.afa.uncompiledAfa.transitionInfo[startState];
                foreach (var edge in outgoingEdgeDictionary)
                {
                    var targetNode = edge.Key;
                    var arc        = edge.Value;
                    if (arc is ListElementArc <TPayload, TRegister> leArc)
                    {
                        var edgeInfo = new EdgeInfo()
                        {
                            Type = EdgeInfo.EdgeType.List,
                            EpsilonReachableNodes = EpsilonClosure(stream.afa, targetNode),
                            Fence    = (ts, evs, reg) => leArc.Fence.Inline(ts, evs, reg),
                            Transfer = leArc.Transfer == null ? ((Func <string, string, string, string>)null) : (ts, evs, reg) => leArc.Transfer.Inline(ts, evs, reg),
                        };
                        edgeList2.Add(edgeInfo);
                    }
                }

                template.newActivationInfo.Add(Tuple.Create(startState, edgeList2));
            }

            return(template.Generate <TKey, TPayload, TRegister, TAccumulator>());
        }
コード例 #9
0
        internal static Tuple <Type, string> GenerateAFA <TKey, TPayload, TRegister, TAccumulator>(
            AfaStreamable <TKey, TPayload, TRegister, TAccumulator> stream)
        {
            Contract.Requires(stream != null);
            Contract.Ensures(Contract.Result <Tuple <Type, string> >() == null || typeof(UnaryPipe <TKey, TPayload, TRegister>).GetTypeInfo().IsAssignableFrom(Contract.Result <Tuple <Type, string> >().Item1));

            var className = string.Format("Generated{1}AfaMultiEventList_{0}", AFASequenceNumber++, typeof(TKey).Equals(typeof(Empty)) ? string.Empty : "Grouped");
            var template  = new AfaMultiEventListTemplate(className, typeof(TKey), typeof(TPayload), typeof(TRegister), typeof(TAccumulator))
            {
                TKey = typeof(TKey).GetCSharpSourceSyntax()
            };
            var payloadRepresentation = new ColumnarRepresentation(typeof(TPayload));

            template.isFinal                   = stream.afa.isFinal;
            template.hasOutgoingArcs           = stream.afa.hasOutgoingArcs;
            template.startStates               = stream.afa.startStates;
            template.AllowOverlappingInstances = stream.afa.uncompiledAfa.AllowOverlappingInstances;
            template.payloadIsAnon             = typeof(TPayload).IsAnonymousTypeName();
            template.payloadHasNoFields        = payloadRepresentation.noFields;

            var d1          = stream.afa.uncompiledAfa.transitionInfo;
            var orderedKeys = d1.Keys.OrderBy(e => e).ToArray();

            for (int i = 0; i < orderedKeys.Length; i++)
            {
                var sourceNodeNumber        = orderedKeys[i];
                var outgoingEdgesDictionary = d1[sourceNodeNumber];
                var orderedTargetNodes      = outgoingEdgesDictionary.Keys.OrderBy(e => e).ToArray();
                var edgeList = new List <EdgeInfo>();
                for (int j = 0; j < orderedTargetNodes.Length; j++)
                {
                    var targetNodeNumber = orderedTargetNodes[j];
                    var edge             = outgoingEdgesDictionary[targetNodeNumber];
                    if (edge is MultiElementArc <TPayload, TRegister, TAccumulator> multiArc)
                    {
                        var multiEdgeInfo = new MultiEdgeInfo()
                        {
                            SourceNode            = sourceNodeNumber,
                            TargetNode            = targetNodeNumber,
                            fromStartState        = stream.afa.startStates.Any(n => n == sourceNodeNumber),
                            EpsilonReachableNodes = EpsilonClosure(stream.afa, targetNodeNumber),
                            Initialize            = (ts, reg) => multiArc.Initialize.Inline(ts, reg),
                            Accumulate            = (ts, ev, reg, acc) => multiArc.Accumulate.Inline(ts, ev, reg, acc),
                            Fence = (ts, acc, reg) => multiArc.Fence.Inline(ts, acc, reg),
                        };

                        multiEdgeInfo.Transfer = multiArc.Transfer == null
                            ? (Func <string, string, string, string>)null
                            : ((ts, acc, reg) => multiArc.Transfer.Inline(ts, acc, reg));

                        if (multiArc.Dispose == null)
                        {
                            multiEdgeInfo.Dispose = (acc) => "// no dispose function";
                        }
                        else
                        {
                            multiEdgeInfo.Dispose = (acc) => multiArc.Dispose.Inline(acc);
                        }

                        multiEdgeInfo.SkipToEnd = multiArc.SkipToEnd == null
                            ? (Func <string, string, string, string>)null
                            : ((ts, ev, acc) => multiArc.SkipToEnd.Inline(ts, ev, acc));

                        edgeList.Add(multiEdgeInfo);
                        continue;
                    }
                    if (edge is SingleElementArc <TPayload, TRegister> singleArc)
                    {
                        var edgeInfo = CreateSingleEdgeInfo(stream, targetNodeNumber, singleArc, "payloadoffset");
                        edgeList.Add(edgeInfo);
                        continue;
                    }
                    if (edge is ListElementArc <TPayload, TRegister> listArc)
                    {
                        var edgeInfo = CreateListEdgeInfo(stream, payloadRepresentation, targetNodeNumber, listArc, "payloadoffset");
                        edgeList.Add(edgeInfo);
                        continue;
                    }
                }
                template.edgeInfos.Add(Tuple.Create(sourceNodeNumber, edgeList));
            }
            for (int i = 0; i < stream.afa.startStates.Length; i++)
            {
                var startState             = stream.afa.startStates[i];
                var edgeList2              = new List <EdgeInfo>();
                var outgoingEdgeDictionary = stream.afa.uncompiledAfa.transitionInfo[startState];
                foreach (var edge in outgoingEdgeDictionary)
                {
                    var targetNode = edge.Key;
                    var arc        = edge.Value;
                    if (arc is MultiElementArc <TPayload, TRegister, TAccumulator> multiArc)
                    {
                        var eps = EpsilonClosure(stream.afa, targetNode);

                        var multiEdgeInfo = new MultiEdgeInfo()
                        {
                            SourceNode            = startState,
                            TargetNode            = targetNode,
                            fromStartState        = true,
                            EpsilonReachableNodes = EpsilonClosure(stream.afa, targetNode),
                            Initialize            = (ts, reg) => multiArc.Initialize.Inline(ts, reg),
                            Accumulate            = (ts, ev, reg, acc) => multiArc.Accumulate.Inline(ts, ev, reg, acc),
                            Fence = (ts, acc, reg) => multiArc.Fence.Inline(ts, acc, reg),
                        };

                        multiEdgeInfo.Transfer = multiArc.Transfer == null
                            ? (Func <string, string, string, string>)null
                            : ((ts, acc, reg) => multiArc.Transfer.Inline(ts, acc, reg));

                        if (multiArc.Dispose == null)
                        {
                            multiEdgeInfo.Dispose = (acc) => "// no dispose function";
                        }
                        else
                        {
                            multiEdgeInfo.Dispose = (acc) => multiArc.Dispose.Inline(acc);
                        }

                        multiEdgeInfo.SkipToEnd = multiArc.SkipToEnd == null
                            ? (Func <string, string, string, string>)null
                            : ((ts, ev, acc) => multiArc.SkipToEnd.Inline(ts, ev, acc));

                        edgeList2.Add(multiEdgeInfo);
                        continue;
                    }
                    if (arc is SingleElementArc <TPayload, TRegister> singleArc)
                    {
                        var edgeInfo = CreateSingleEdgeInfo(stream, targetNode, singleArc, "payloadoffset");
                        edgeList2.Add(edgeInfo);
                        continue;
                    }
                    if (arc is ListElementArc <TPayload, TRegister> listArc)
                    {
                        var edgeInfo = CreateListEdgeInfo(stream, payloadRepresentation, targetNode, listArc, "payloadoffset");
                        edgeList2.Add(edgeInfo);
                        continue;
                    }
                }

                template.startEdgeInfos.Add(Tuple.Create(startState, edgeList2));
            }

            template.isSyncTimeSimultaneityFree = true; // The handwritten version doesn't make a distinction.
            template.keyEqualityComparer        =
                (left, right) =>
                stream.Properties.KeyEqualityComparer.GetEqualsExpr().Inline(left, right);

            return(template.Generate <TKey, TPayload, TRegister, TAccumulator>());
        }
コード例 #10
0
        protected static EdgeInfo CreateSingleEdgeInfo <TKey, TPayload, TRegister, TAccumulator>(AfaStreamable <TKey, TPayload, TRegister, TAccumulator> stream, int targetNodeNumber, SingleElementArc <TPayload, TRegister> searc, string indexVariableName)
        {
            var edgeInfo = new EdgeInfo()
            {
                Type = EdgeInfo.EdgeType.Single,
                EpsilonReachableNodes = EpsilonClosure(stream.afa, targetNodeNumber),
                SourceNode            = targetNodeNumber,
                Fence = (ts, ev, reg) => searc.Fence.Inline(ts, ev, reg),
            };

            if (searc.Transfer == null)
            {
                edgeInfo.Transfer = null;
            }
            else
            {
                edgeInfo.Transfer = (ts, ev, reg) => searc.Transfer.Inline(ts, ev, reg);
            }
            return(edgeInfo);
        }
コード例 #11
0
        internal static Tuple <Type, string> GenerateAFA <TKey, TPayload, TRegister, TAccumulator>(
            AfaStreamable <TKey, TPayload, TRegister, TAccumulator> stream)
        {
            Contract.Requires(stream != null);
            Contract.Ensures(Contract.Result <Tuple <Type, string> >() == null || typeof(UnaryPipe <TKey, TPayload, TRegister>).GetTypeInfo().IsAssignableFrom(Contract.Result <Tuple <Type, string> >().Item1));

            var className = $"GeneratedGroupedAfaMultiEvent_{AFASequenceNumber++}";
            var template  = new GroupedAfaMultiEventTemplate(className, typeof(TKey), typeof(TPayload), typeof(TRegister), typeof(TAccumulator))
            {
                isFinal                    = stream.afa.isFinal,
                hasOutgoingArcs            = stream.afa.hasOutgoingArcs,
                startStates                = stream.afa.startStates,
                AllowOverlappingInstances  = stream.afa.uncompiledAfa.AllowOverlappingInstances,
                isSyncTimeSimultaneityFree = true, // The handwritten version doesn't make a distinction.
                keyEqualityComparer        =
                    (left, right) =>
                    stream.Properties.KeyEqualityComparer.GetEqualsExpr().Inline(left, right),
            };

            var d1          = stream.afa.uncompiledAfa.transitionInfo;
            var orderedKeys = d1.Keys.OrderBy(e => e).ToArray();

            for (int i = 0; i < orderedKeys.Length; i++)
            {
                var sourceNodeNumber        = orderedKeys[i];
                var outgoingEdgesDictionary = d1[sourceNodeNumber];
                var orderedTargetNodes      = outgoingEdgesDictionary.Keys.OrderBy(e => e).ToArray();
                var edgeList = new List <MultiEdgeInfo>();
                for (int j = 0; j < orderedTargetNodes.Length; j++)
                {
                    var targetNodeNumber = orderedTargetNodes[j];
                    var edge             = outgoingEdgesDictionary[targetNodeNumber];
                    if (edge is MultiElementArc <TPayload, TRegister, TAccumulator> multiArc)
                    {
                        var multiEdgeInfo = new MultiEdgeInfo()
                        {
                            SourceNode            = sourceNodeNumber,
                            TargetNode            = targetNodeNumber,
                            fromStartState        = stream.afa.startStates.Any(n => n == sourceNodeNumber),
                            EpsilonReachableNodes = EpsilonClosure(stream.afa, targetNodeNumber),
                            Initialize            = (ts, reg) => multiArc.Initialize.Inline(ts, reg),
                            Accumulate            = (ts, ev, reg, acc) =>
                            {
                                var transformedAccumulate = Extensions.TransformFunction <TKey, TPayload>(multiArc.Accumulate, 1, batchVariableName: "sourceBatch");
                                return(transformedAccumulate.Inline(ts, reg, acc));
                            },
                            Fence = (ts, acc, reg) => multiArc.Fence.Inline(ts, acc, reg),
                        };

                        multiEdgeInfo.Transfer = multiArc.Transfer == null
                            ? (Func <string, string, string, string>)null
                            : ((ts, acc, reg) => multiArc.Transfer.Inline(ts, acc, reg));

                        if (multiArc.Dispose == null)
                        {
                            multiEdgeInfo.Dispose = (acc) => "// no dispose function";
                        }
                        else
                        {
                            multiEdgeInfo.Dispose = (acc) => multiArc.Dispose.Inline(acc);
                        }

                        multiEdgeInfo.SkipToEnd = multiArc.SkipToEnd == null
                            ? (Func <string, string, string, string>)null
                            : ((ts, ev, acc) => multiArc.SkipToEnd.Inline(ts, ev, acc));

                        edgeList.Add(multiEdgeInfo);
                    }
                }
                template.edgeInfos.Add(Tuple.Create(sourceNodeNumber, edgeList));
            }
            for (int i = 0; i < stream.afa.startStates.Length; i++)
            {
                var startState             = stream.afa.startStates[i];
                var edgeList2              = new List <MultiEdgeInfo>();
                var outgoingEdgeDictionary = stream.afa.uncompiledAfa.transitionInfo[startState];
                foreach (var edge in outgoingEdgeDictionary)
                {
                    var targetNode = edge.Key;
                    var arc        = edge.Value;
                    if (arc is MultiElementArc <TPayload, TRegister, TAccumulator> multiArc)
                    {
                        var eps = EpsilonClosure(stream.afa, targetNode);

                        var multiEdgeInfo = new MultiEdgeInfo()
                        {
                            SourceNode            = startState,
                            TargetNode            = targetNode,
                            fromStartState        = true,
                            EpsilonReachableNodes = EpsilonClosure(stream.afa, targetNode),
                            Initialize            = (ts, reg) => multiArc.Initialize.Inline(ts, reg),
                            Accumulate            = (ts, ev, reg, acc) =>
                            {
                                var transformedAccumulate = Extensions.TransformFunction <TKey, TPayload>(multiArc.Accumulate, 1, batchVariableName: "sourceBatch");
                                return(transformedAccumulate.Inline(ts, reg, acc));
                            },
                            Fence = (ts, acc, reg) => multiArc.Fence.Inline(ts, acc, reg),
                        };

                        multiEdgeInfo.Transfer = multiArc.Transfer == null
                            ? (Func <string, string, string, string>)null
                            : ((ts, acc, reg) => multiArc.Transfer.Inline(ts, acc, reg));

                        if (multiArc.Dispose == null)
                        {
                            multiEdgeInfo.Dispose = (acc) => "// no dispose function";
                        }
                        else
                        {
                            multiEdgeInfo.Dispose = (acc) => multiArc.Dispose.Inline(acc);
                        }

                        multiEdgeInfo.SkipToEnd = multiArc.SkipToEnd == null
                            ? (Func <string, string, string, string>)null
                            : ((ts, ev, acc) => multiArc.SkipToEnd.Inline(ts, ev, acc));

                        edgeList2.Add(multiEdgeInfo);
                    }
                }

                template.startEdgeInfos.Add(Tuple.Create(startState, edgeList2));
            }

            return(template.Generate <TKey, TPayload, TRegister, TAccumulator>());
        }