aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/CommunicationTracker.java
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-10-15 15:57:52 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-10-15 15:57:52 +0200
commitacb5e04319883ceb0dffe25635db5dc22448f247 (patch)
treea58ba07ae482ff1b850d040bb263e38ae0d50876 /subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/CommunicationTracker.java
parentrefactor(interpreter): generify RepresentativeElectionAlgorithm (diff)
downloadrefinery-acb5e04319883ceb0dffe25635db5dc22448f247.tar.gz
refinery-acb5e04319883ceb0dffe25635db5dc22448f247.tar.zst
refinery-acb5e04319883ceb0dffe25635db5dc22448f247.zip
refactor(interpreter): communication tracker algorithm
Use a faster algorithm to detect cycles in the RETE network. Only if cycles are detected fall back to the transitive closure algorithm to construct the SCCs and the reduced graph.
Diffstat (limited to 'subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/CommunicationTracker.java')
-rw-r--r--subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/CommunicationTracker.java46
1 files changed, 35 insertions, 11 deletions
diff --git a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/CommunicationTracker.java b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/CommunicationTracker.java
index 2e8eb338..1d089ba6 100644
--- a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/CommunicationTracker.java
+++ b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/CommunicationTracker.java
@@ -1,5 +1,6 @@
1/******************************************************************************* 1/*******************************************************************************
2 * Copyright (c) 2010-2017, Tamas Szabo, Istvan Rath and Daniel Varro 2 * Copyright (c) 2010-2017, Tamas Szabo, Istvan Rath and Daniel Varro
3 * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/>
3 * This program and the accompanying materials are made available under the 4 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at 5 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html. 6 * http://www.eclipse.org/legal/epl-v20.html.
@@ -8,12 +9,13 @@
8 *******************************************************************************/ 9 *******************************************************************************/
9package tools.refinery.interpreter.rete.network.communication; 10package tools.refinery.interpreter.rete.network.communication;
10 11
12import org.apache.log4j.Logger;
13import org.jetbrains.annotations.Nullable;
11import tools.refinery.interpreter.matchers.tuple.TupleMask; 14import tools.refinery.interpreter.matchers.tuple.TupleMask;
12import tools.refinery.interpreter.rete.aggregation.IAggregatorNode; 15import tools.refinery.interpreter.rete.aggregation.IAggregatorNode;
13import tools.refinery.interpreter.rete.boundary.ExternalInputEnumeratorNode; 16import tools.refinery.interpreter.rete.boundary.ExternalInputEnumeratorNode;
14import tools.refinery.interpreter.rete.eval.RelationEvaluatorNode; 17import tools.refinery.interpreter.rete.eval.RelationEvaluatorNode;
15import tools.refinery.interpreter.rete.index.*; 18import tools.refinery.interpreter.rete.index.*;
16import tools.refinery.interpreter.rete.itc.alg.incscc.IncSCCAlg;
17import tools.refinery.interpreter.rete.itc.alg.misc.topsort.TopologicalSorting; 19import tools.refinery.interpreter.rete.itc.alg.misc.topsort.TopologicalSorting;
18import tools.refinery.interpreter.rete.itc.graphimpl.Graph; 20import tools.refinery.interpreter.rete.itc.graphimpl.Graph;
19import tools.refinery.interpreter.rete.network.*; 21import tools.refinery.interpreter.rete.network.*;
@@ -61,7 +63,7 @@ public abstract class CommunicationTracker {
61 /** 63 /**
62 * Incremental SCC information about the dependency graph 64 * Incremental SCC information about the dependency graph
63 */ 65 */
64 protected final IncSCCAlg<Node> sccInformationProvider; 66 private final NetworkComponentDetector componentDetector;
65 67
66 /** 68 /**
67 * Precomputed node -> communication group map 69 * Precomputed node -> communication group map
@@ -76,9 +78,9 @@ public abstract class CommunicationTracker {
76 // groups should have a simple integer flag which represents its position in a priority queue 78 // groups should have a simple integer flag which represents its position in a priority queue
77 // priority queue only contains the ACTIVE groups 79 // priority queue only contains the ACTIVE groups
78 80
79 public CommunicationTracker() { 81 public CommunicationTracker(Logger logger) {
80 this.dependencyGraph = new Graph<Node>(); 82 this.dependencyGraph = new Graph<Node>();
81 this.sccInformationProvider = new IncSCCAlg<Node>(this.dependencyGraph); 83 this.componentDetector = new NetworkComponentDetector(logger, dependencyGraph);
82 this.groupQueue = new PriorityQueue<CommunicationGroup>(); 84 this.groupQueue = new PriorityQueue<CommunicationGroup>();
83 this.groupMap = new HashMap<Node, CommunicationGroup>(); 85 this.groupMap = new HashMap<Node, CommunicationGroup>();
84 } 86 }
@@ -91,11 +93,33 @@ public abstract class CommunicationTracker {
91 return this.groupMap.get(node); 93 return this.groupMap.get(node);
92 } 94 }
93 95
96 @Nullable
97 protected Set<Node> getPartition(Node node) {
98 return componentDetector.getPartition(node);
99 }
100
101 protected boolean isSingleton(Node node) {
102 var partition = getPartition(node);
103 return partition == null || partition.isEmpty();
104 }
105
106 protected Node getRepresentative(Node node) {
107 return componentDetector.getRepresentative(node);
108 }
109
110 protected boolean hasOutgoingEdges(Node representative) {
111 return componentDetector.hasOutgoingEdges(representative);
112 }
113
114 protected Graph<Node> getReducedGraph() {
115 return componentDetector.getReducedGraph();
116 }
117
94 private void precomputeGroups() { 118 private void precomputeGroups() {
95 groupMap.clear(); 119 groupMap.clear();
96 120
97 // reconstruct group map from dependency graph 121 // reconstruct group map from dependency graph
98 final Graph<Node> reducedGraph = sccInformationProvider.getReducedGraph(); 122 final Graph<Node> reducedGraph = getReducedGraph();
99 final List<Node> representatives = TopologicalSorting.compute(reducedGraph); 123 final List<Node> representatives = TopologicalSorting.compute(reducedGraph);
100 124
101 for (int i = 0; i < representatives.size(); i++) { // groups for SCC representatives 125 for (int i = 0; i < representatives.size(); i++) { // groups for SCC representatives
@@ -107,7 +131,7 @@ public abstract class CommunicationTracker {
107 maxGroupId = representatives.size() - 1; 131 maxGroupId = representatives.size() - 1;
108 132
109 for (final Node node : dependencyGraph.getAllNodes()) { // extend group map to the rest of nodes 133 for (final Node node : dependencyGraph.getAllNodes()) { // extend group map to the rest of nodes
110 final Node representative = sccInformationProvider.getRepresentative(node); 134 final Node representative = getRepresentative(node);
111 final CommunicationGroup group = groupMap.get(representative); 135 final CommunicationGroup group = groupMap.get(representative);
112 if (representative != node) { 136 if (representative != node) {
113 addToGroup(node, group); 137 addToGroup(node, group);
@@ -285,9 +309,9 @@ public abstract class CommunicationTracker {
285 309
286 // query all these information before the actual edge insertion 310 // query all these information before the actual edge insertion
287 // because SCCs may be unified during the process 311 // because SCCs may be unified during the process
288 final Node sourceRepresentative = sccInformationProvider.getRepresentative(source); 312 final Node sourceRepresentative = getRepresentative(source);
289 final Node targetRepresentative = sccInformationProvider.getRepresentative(target); 313 final Node targetRepresentative = getRepresentative(target);
290 final boolean targetHadOutgoingEdges = sccInformationProvider.hasOutgoingEdges(targetRepresentative); 314 final boolean targetHadOutgoingEdges = hasOutgoingEdges(targetRepresentative);
291 315
292 // insert the edge 316 // insert the edge
293 dependencyGraph.insertEdge(source, target); 317 dependencyGraph.insertEdge(source, target);
@@ -372,8 +396,8 @@ public abstract class CommunicationTracker {
372 // delete the edge first, and then query the SCC info provider 396 // delete the edge first, and then query the SCC info provider
373 this.dependencyGraph.deleteEdgeIfExists(source, target); 397 this.dependencyGraph.deleteEdgeIfExists(source, target);
374 398
375 final Node sourceRepresentative = sccInformationProvider.getRepresentative(source); 399 final Node sourceRepresentative = getRepresentative(source);
376 final Node targetRepresentative = sccInformationProvider.getRepresentative(target); 400 final Node targetRepresentative = getRepresentative(target);
377 401
378 // if they are still in the same SCC, 402 // if they are still in the same SCC,
379 // then this deletion did not affect the SCCs, 403 // then this deletion did not affect the SCCs,