aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/index/StandardIndexer.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/index/StandardIndexer.java')
-rw-r--r--subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/index/StandardIndexer.java127
1 files changed, 127 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/index/StandardIndexer.java b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/index/StandardIndexer.java
new file mode 100644
index 00000000..9847a8dd
--- /dev/null
+++ b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/index/StandardIndexer.java
@@ -0,0 +1,127 @@
1/*******************************************************************************
2 * Copyright (c) 2004-2008 Gabor Bergmann and Daniel Varro
3 * 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 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9
10package tools.refinery.viatra.runtime.rete.index;
11
12import java.util.Collection;
13import java.util.List;
14
15import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
16import tools.refinery.viatra.runtime.matchers.tuple.TupleMask;
17import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory;
18import tools.refinery.viatra.runtime.matchers.util.Direction;
19import tools.refinery.viatra.runtime.rete.network.BaseNode;
20import tools.refinery.viatra.runtime.rete.network.NetworkStructureChangeSensitiveNode;
21import tools.refinery.viatra.runtime.rete.network.ReteContainer;
22import tools.refinery.viatra.runtime.rete.network.Supplier;
23import tools.refinery.viatra.runtime.rete.network.communication.Timestamp;
24import tools.refinery.viatra.runtime.rete.traceability.TraceInfo;
25
26/**
27 * An abstract standard implementation of the Indexer interface, providing common bookkeeping functionality.
28 *
29 * @author Gabor Bergmann
30 *
31 */
32public abstract class StandardIndexer extends BaseNode implements Indexer, NetworkStructureChangeSensitiveNode {
33
34 protected Supplier parent;
35 private final List<IndexerListener> originalListeners;
36 private final List<IndexerListener> proxyListeners;
37 protected TupleMask mask;
38
39 public StandardIndexer(ReteContainer reteContainer, TupleMask mask) {
40 super(reteContainer);
41 this.parent = null;
42 this.mask = mask;
43 this.originalListeners = CollectionsFactory.createObserverList();
44 this.proxyListeners = CollectionsFactory.createObserverList();
45 }
46
47 /**
48 * @since 2.4
49 */
50 protected void propagate(Direction direction, Tuple updateElement, Tuple signature, boolean change, Timestamp timestamp) {
51 for (IndexerListener listener : proxyListeners) {
52 listener.notifyIndexerUpdate(direction, updateElement, signature, change, timestamp);
53 }
54 }
55
56 @Override
57 public TupleMask getMask() {
58 return mask;
59 }
60
61 @Override
62 public Supplier getParent() {
63 return parent;
64 }
65
66 @Override
67 public void attachListener(IndexerListener listener) {
68 this.getCommunicationTracker().registerDependency(this, listener.getOwner());
69 // obtain the proxy after registering the dependency because then the proxy reflects the new SCC structure
70 final IndexerListener proxy = this.getCommunicationTracker().proxifyIndexerListener(this, listener);
71 // See Bug 518434
72 // Must add to the first position, so that the later listeners are notified earlier.
73 // Thus if the beta node added as listener is also an indirect descendant of the same indexer on its opposite slot,
74 // then the beta node is connected later than its ancestor's listener, therefore it will be notified earlier,
75 // eliminating duplicate insertions and lost deletions that would result from fall-through update propagation
76 this.originalListeners.add(0, listener);
77 this.proxyListeners.add(0, proxy);
78 }
79
80 @Override
81 public void detachListener(IndexerListener listener) {
82 this.originalListeners.remove(listener);
83 IndexerListener listenerToRemove = null;
84 for (final IndexerListener proxyListener : this.proxyListeners) {
85 if (proxyListener.getOwner() == listener.getOwner()) {
86 listenerToRemove = proxyListener;
87 break;
88 }
89 }
90 assert listenerToRemove != null;
91 this.proxyListeners.remove(listenerToRemove);
92 this.getCommunicationTracker().unregisterDependency(this, listener.getOwner());
93 }
94
95 @Override
96 public void networkStructureChanged() {
97 this.proxyListeners.clear();
98 for (final IndexerListener original : this.originalListeners) {
99 this.proxyListeners.add(this.getCommunicationTracker().proxifyIndexerListener(this, original));
100 }
101 }
102
103 @Override
104 public Collection<IndexerListener> getListeners() {
105 return proxyListeners;
106 }
107
108 @Override
109 public ReteContainer getContainer() {
110 return reteContainer;
111 }
112
113 @Override
114 protected String toStringCore() {
115 return super.toStringCore() + "(" + parent + "/" + mask + ")";
116 }
117
118 @Override
119 public void assignTraceInfo(TraceInfo traceInfo) {
120 super.assignTraceInfo(traceInfo);
121 if (traceInfo.propagateFromIndexerToSupplierParent())
122 if (parent != null)
123 parent.acceptPropagatedTraceInfo(traceInfo);
124 }
125
126
127}