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>()); }
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; } }
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> > >(); } }
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)); } }
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)); } }
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); }
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); }
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>()); }
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>()); }
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); }
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>()); }