aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/graphimpl/Graph.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/graphimpl/Graph.java')
-rw-r--r--subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/graphimpl/Graph.java185
1 files changed, 185 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/graphimpl/Graph.java b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/graphimpl/Graph.java
new file mode 100644
index 00000000..91604cb2
--- /dev/null
+++ b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/graphimpl/Graph.java
@@ -0,0 +1,185 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2012, Tamas Szabo, Istvan Rath 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.itc.graphimpl;
11
12import tools.refinery.viatra.runtime.rete.itc.igraph.IGraphDataSource;
13import tools.refinery.viatra.runtime.rete.itc.igraph.IGraphObserver;
14import tools.refinery.viatra.runtime.rete.itc.igraph.IBiDirectionalGraphDataSource;
15import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory;
16import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory.MemoryType;
17import tools.refinery.viatra.runtime.matchers.util.IMemoryView;
18import tools.refinery.viatra.runtime.matchers.util.IMultiLookup;
19
20import java.util.List;
21import java.util.Map;
22import java.util.Map.Entry;
23import java.util.Set;
24
25public class Graph<V> implements IGraphDataSource<V>, IBiDirectionalGraphDataSource<V> {
26
27 // source -> target -> count
28 private IMultiLookup<V, V> outgoingEdges;
29 // target -> source -> count
30 private IMultiLookup<V, V> incomingEdges;
31
32 private Set<V> nodes;
33
34 private List<IGraphObserver<V>> observers;
35
36 public Graph() {
37 outgoingEdges = CollectionsFactory.createMultiLookup(Object.class, MemoryType.MULTISETS, Object.class);
38 incomingEdges = CollectionsFactory.createMultiLookup(Object.class, MemoryType.MULTISETS, Object.class);
39 nodes = CollectionsFactory.createSet();
40 observers = CollectionsFactory.createObserverList();
41 }
42
43 public void insertEdge(V source, V target) {
44 outgoingEdges.addPair(source, target);
45 incomingEdges.addPair(target, source);
46
47 for (IGraphObserver<V> go : observers) {
48 go.edgeInserted(source, target);
49 }
50 }
51
52 /**
53 * No-op if trying to delete edge that does not exist
54 *
55 * @since 2.0
56 * @see #deleteEdgeIfExists(Object, Object)
57 */
58 public void deleteEdgeIfExists(V source, V target) {
59 boolean containedEdge = outgoingEdges.lookupOrEmpty(source).containsNonZero(target);
60 if (containedEdge) {
61 deleteEdgeThatExists(source, target);
62 }
63 }
64
65 /**
66 * @throws IllegalStateException
67 * if trying to delete edge that does not exist
68 * @since 2.0
69 * @see #deleteEdgeIfExists(Object, Object)
70 */
71 public void deleteEdgeThatExists(V source, V target) {
72 outgoingEdges.removePair(source, target);
73 incomingEdges.removePair(target, source);
74 for (IGraphObserver<V> go : observers) {
75 go.edgeDeleted(source, target);
76 }
77 }
78
79 /**
80 * @deprecated use explicitly {@link #deleteEdgeThatExists(Object, Object)} or
81 * {@link #deleteEdgeIfExists(Object, Object)} instead. To preserve backwards compatibility, this method
82 * delegates to the latter.
83 *
84 */
85 @Deprecated
86 public void deleteEdge(V source, V target) {
87 deleteEdgeIfExists(source, target);
88 }
89
90 /**
91 * Insert the given node into the graph.
92 */
93 public void insertNode(V node) {
94 if (nodes.add(node)) {
95 for (IGraphObserver<V> go : observers) {
96 go.nodeInserted(node);
97 }
98 }
99 }
100
101 /**
102 * Deletes the given node AND all of the edges going in and out from the node.
103 */
104 public void deleteNode(V node) {
105 if (nodes.remove(node)) {
106 IMemoryView<V> incomingView = incomingEdges.lookup(node);
107 if (incomingView != null) {
108 Map<V, Integer> incoming = CollectionsFactory.createMap(incomingView.asMap());
109
110 for (Entry<V, Integer> entry : incoming.entrySet()) {
111 for (int i = 0; i < entry.getValue(); i++) {
112 deleteEdgeThatExists(entry.getKey(), node);
113 }
114 }
115 }
116
117 IMemoryView<V> outgoingView = outgoingEdges.lookup(node);
118 if (outgoingView != null) {
119 Map<V, Integer> outgoing = CollectionsFactory.createMap(outgoingView.asMap());
120
121 for (Entry<V, Integer> entry : outgoing.entrySet()) {
122 for (int i = 0; i < entry.getValue(); i++) {
123 deleteEdgeThatExists(node, entry.getKey());
124 }
125 }
126 }
127
128 for (IGraphObserver<V> go : observers) {
129 go.nodeDeleted(node);
130 }
131 }
132 }
133
134 @Override
135 public void attachObserver(IGraphObserver<V> go) {
136 observers.add(go);
137 }
138
139 @Override
140 public void attachAsFirstObserver(IGraphObserver<V> observer) {
141 observers.add(0, observer);
142 }
143
144 @Override
145 public void detachObserver(IGraphObserver<V> go) {
146 observers.remove(go);
147 }
148
149 @Override
150 public Set<V> getAllNodes() {
151 return nodes;
152 }
153
154 @Override
155 public IMemoryView<V> getTargetNodes(V source) {
156 return outgoingEdges.lookupOrEmpty(source);
157 }
158
159 @Override
160 public IMemoryView<V> getSourceNodes(V target) {
161 return incomingEdges.lookupOrEmpty(target);
162 }
163
164 @Override
165 public String toString() {
166 StringBuilder sb = new StringBuilder();
167 sb.append("nodes = ");
168 for (V n : getAllNodes()) {
169 sb.append(n.toString());
170 sb.append(" ");
171 }
172 sb.append(" edges = ");
173 for (V source : outgoingEdges.distinctKeys()) {
174 IMemoryView<V> targets = outgoingEdges.lookup(source);
175 for (V target : targets.distinctValues()) {
176 int count = targets.getCount(target);
177 for (int i = 0; i < count; i++) {
178 sb.append("(" + source + "," + target + ") ");
179 }
180 }
181 }
182 return sb.toString();
183 }
184
185}