aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/rete/network/RepresentativeElectionNode.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/rete/network/RepresentativeElectionNode.java')
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/rete/network/RepresentativeElectionNode.java120
1 files changed, 120 insertions, 0 deletions
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/rete/network/RepresentativeElectionNode.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/rete/network/RepresentativeElectionNode.java
new file mode 100644
index 00000000..701f6ffe
--- /dev/null
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/rete/network/RepresentativeElectionNode.java
@@ -0,0 +1,120 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro
3 * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/>
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v. 2.0 which is available at
6 * http://www.eclipse.org/legal/epl-v20.html.
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package tools.refinery.store.query.viatra.internal.rete.network;
10
11import org.eclipse.viatra.query.runtime.base.itc.graphimpl.Graph;
12import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple;
13import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
14import org.eclipse.viatra.query.runtime.matchers.util.Clearable;
15import org.eclipse.viatra.query.runtime.matchers.util.Direction;
16import org.eclipse.viatra.query.runtime.matchers.util.timeline.Timeline;
17import org.eclipse.viatra.query.runtime.rete.network.ReteContainer;
18import org.eclipse.viatra.query.runtime.rete.network.communication.Timestamp;
19import org.eclipse.viatra.query.runtime.rete.single.SingleInputNode;
20
21import java.util.Collection;
22import java.util.Map;
23
24public class RepresentativeElectionNode extends SingleInputNode implements Clearable {
25 private final RepresentativeElectionAlgorithm.Factory algorithmFactory;
26 private Graph<Object> graph;
27 private RepresentativeElectionAlgorithm algorithm;
28
29 public RepresentativeElectionNode(ReteContainer reteContainer,
30 RepresentativeElectionAlgorithm.Factory algorithmFactory) {
31 super(reteContainer);
32 this.algorithmFactory = algorithmFactory;
33 graph = new Graph<>();
34 algorithm = algorithmFactory.create(graph);
35 algorithm.setObserver(this);
36 reteContainer.registerClearable(this);
37 }
38
39 @Override
40 public void networkStructureChanged() {
41 if (reteContainer.isTimelyEvaluation() && reteContainer.getCommunicationTracker().isInRecursiveGroup(this)) {
42 throw new IllegalStateException(this + " cannot be used in recursive differential dataflow evaluation!");
43 }
44 super.networkStructureChanged();
45 }
46
47 public void reinitializeWith(Collection<Tuple> tuples) {
48 algorithm.dispose();
49 graph = new Graph<>();
50 for (var tuple : tuples) {
51 insertEdge(tuple.get(0), tuple.get(1));
52 }
53 algorithm = algorithmFactory.create(graph);
54 algorithm.setObserver(this);
55 }
56
57 public void tupleChanged(Object source, Object representative, Direction direction) {
58 var tuple = Tuples.staticArityFlatTupleOf(source, representative);
59 propagateUpdate(direction, tuple, Timestamp.ZERO);
60 }
61
62 @Override
63 public void clear() {
64 algorithm.dispose();
65 graph = new Graph<>();
66 algorithm = algorithmFactory.create(graph);
67 }
68
69 @Override
70 public void update(Direction direction, Tuple updateElement, Timestamp timestamp) {
71 var source = updateElement.get(0);
72 var target = updateElement.get(1);
73 switch (direction) {
74 case INSERT -> insertEdge(source, target);
75 case DELETE -> deleteEdge(source, target);
76 default -> throw new IllegalArgumentException("Unknown direction: " + direction);
77 }
78 }
79
80 private void insertEdge(Object source, Object target) {
81 graph.insertNode(source);
82 graph.insertNode(target);
83 graph.insertEdge(source, target);
84 }
85
86 private void deleteEdge(Object source, Object target) {
87 graph.deleteEdgeIfExists(source, target);
88 if (isIsolated(source)) {
89 graph.deleteNode(source);
90 }
91 if (!source.equals(target) && isIsolated(target)) {
92 graph.deleteNode(target);
93 }
94 }
95
96 private boolean isIsolated(Object node) {
97 return graph.getTargetNodes(node).isEmpty() && graph.getSourceNodes(node).isEmpty();
98 }
99
100 @Override
101 public void pullInto(Collection<Tuple> collector, boolean flush) {
102 for (var entry : algorithm.getComponents().entrySet()) {
103 var representative = entry.getKey();
104 for (var node : entry.getValue()) {
105 collector.add(Tuples.staticArityFlatTupleOf(node, representative));
106 }
107 }
108 }
109
110 @Override
111 public void pullIntoWithTimeline(Map<Tuple, Timeline<Timestamp>> collector, boolean flush) {
112 // Use all zero timestamps because this node cannot be used in recursive groups anyway.
113 for (var entry : algorithm.getComponents().entrySet()) {
114 var representative = entry.getKey();
115 for (var node : entry.getValue()) {
116 collector.put(Tuples.staticArityFlatTupleOf(node, representative), Timestamp.INSERT_AT_ZERO_TIMELINE);
117 }
118 }
119 }
120}