aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/memories/timely/AbstractTimelyMaskedMemory.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/memories/timely/AbstractTimelyMaskedMemory.java')
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/memories/timely/AbstractTimelyMaskedMemory.java228
1 files changed, 228 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/memories/timely/AbstractTimelyMaskedMemory.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/memories/timely/AbstractTimelyMaskedMemory.java
new file mode 100644
index 00000000..45ce3a4e
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/memories/timely/AbstractTimelyMaskedMemory.java
@@ -0,0 +1,228 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd.
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 *******************************************************************************/
9package tools.refinery.viatra.runtime.matchers.memories.timely;
10
11import java.util.Collection;
12import java.util.Iterator;
13import java.util.Map;
14import java.util.Map.Entry;
15import java.util.Objects;
16import java.util.Set;
17import java.util.TreeMap;
18
19import tools.refinery.viatra.runtime.matchers.memories.MaskedTupleMemory;
20import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
21import tools.refinery.viatra.runtime.matchers.tuple.TupleMask;
22import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory;
23import tools.refinery.viatra.runtime.matchers.util.Direction;
24import tools.refinery.viatra.runtime.matchers.util.Signed;
25import tools.refinery.viatra.runtime.matchers.util.TimelyMemory;
26import tools.refinery.viatra.runtime.matchers.util.timeline.Diff;
27import tools.refinery.viatra.runtime.matchers.util.timeline.Timeline;
28
29/**
30 * Common parts of timely default and timely unary implementations.
31 *
32 * @noextend This class is not intended to be subclassed by clients.
33 * @author Tamas Szabo
34 * @since 2.3
35 */
36abstract class AbstractTimelyMaskedMemory<Timestamp extends Comparable<Timestamp>, KeyType>
37 extends MaskedTupleMemory<Timestamp> {
38
39 protected final TreeMap<Timestamp, Set<KeyType>> foldingStates;
40 protected final Map<KeyType, TimelyMemory<Timestamp>> memoryMap;
41 protected final boolean isLazy;
42
43 public AbstractTimelyMaskedMemory(final TupleMask mask, final Object owner, final boolean isLazy) {
44 super(mask, owner);
45 this.isLazy = isLazy;
46 this.memoryMap = CollectionsFactory.createMap();
47 this.foldingStates = this.isLazy ? CollectionsFactory.createTreeMap() : null;
48 }
49
50 @Override
51 public void initializeWith(final MaskedTupleMemory<Timestamp> other, final Timestamp defaultValue) {
52 final Iterable<Tuple> signatures = other.getSignatures();
53 for (final Tuple signature : signatures) {
54 if (other.isTimely()) {
55 final Map<Tuple, Timeline<Timestamp>> tupleMap = other.getWithTimeline(signature);
56 for (final Entry<Tuple, Timeline<Timestamp>> entry : tupleMap.entrySet()) {
57 for (final Signed<Timestamp> signed : entry.getValue().asChangeSequence()) {
58 if (signed.getDirection() == Direction.DELETE) {
59 this.removeWithTimestamp(entry.getKey(), signed.getPayload());
60 } else {
61 this.addWithTimestamp(entry.getKey(), signed.getPayload());
62 }
63 }
64 }
65 } else {
66 final Collection<Tuple> tuples = other.get(signature);
67 for (final Tuple tuple : tuples) {
68 this.addWithTimestamp(tuple, defaultValue);
69 }
70 }
71 }
72 }
73
74 public boolean isPresentAtInfinityInteral(KeyType key) {
75 final TimelyMemory<Timestamp> values = this.memoryMap.get(key);
76 if (values == null) {
77 return false;
78 } else {
79 return values.getCountAtInfinity() != 0;
80 }
81 }
82
83 @Override
84 public void clear() {
85 this.memoryMap.clear();
86 }
87
88 @Override
89 public int getKeysetSize() {
90 return this.memoryMap.keySet().size();
91 }
92
93 @Override
94 public int getTotalSize() {
95 int i = 0;
96 for (final Entry<KeyType, TimelyMemory<Timestamp>> entry : this.memoryMap.entrySet()) {
97 i += entry.getValue().size();
98 }
99 return i;
100 }
101
102 @Override
103 public Iterator<Tuple> iterator() {
104 return this.memoryMap.values().stream().flatMap(e -> e.keySet().stream()).iterator();
105 }
106
107 protected Collection<Tuple> getInternal(final KeyType key) {
108 final TimelyMemory<Timestamp> memory = this.memoryMap.get(key);
109 if (memory == null) {
110 return null;
111 } else {
112 return memory.getTuplesAtInfinity();
113 }
114 }
115
116 public Map<Tuple, Timeline<Timestamp>> getWithTimestampInternal(final KeyType key) {
117 final TimelyMemory<Timestamp> memory = this.memoryMap.get(key);
118 if (memory == null) {
119 return null;
120 } else {
121 return memory.asMap();
122 }
123 }
124
125 protected Diff<Timestamp> removeInternal(final KeyType key, final Tuple tuple, final Timestamp timestamp) {
126 Timestamp oldResumableTimestamp = null;
127 Timestamp newResumableTimestamp = null;
128
129 final TimelyMemory<Timestamp> keyMemory = this.memoryMap.get(key);
130 if (keyMemory == null) {
131 throw raiseDuplicateDeletion(tuple);
132 }
133
134 if (this.isLazy) {
135 oldResumableTimestamp = keyMemory.getResumableTimestamp();
136 }
137
138 Diff<Timestamp> diff = null;
139 try {
140 diff = keyMemory.remove(tuple, timestamp);
141 } catch (final IllegalStateException e) {
142 throw raiseDuplicateDeletion(tuple);
143 }
144 if (keyMemory.isEmpty()) {
145 this.memoryMap.remove(key);
146 }
147
148 if (this.isLazy) {
149 newResumableTimestamp = keyMemory.getResumableTimestamp();
150 if (!Objects.equals(oldResumableTimestamp, newResumableTimestamp)) {
151 unregisterFoldingState(oldResumableTimestamp, key);
152 registerFoldingState(newResumableTimestamp, key);
153 }
154 }
155
156 return diff;
157 }
158
159 protected Diff<Timestamp> addInternal(final KeyType key, final Tuple tuple, final Timestamp timestamp) {
160 Timestamp oldResumableTimestamp = null;
161 Timestamp newResumableTimestamp = null;
162
163 final TimelyMemory<Timestamp> keyMemory = this.memoryMap.computeIfAbsent(key,
164 k -> new TimelyMemory<Timestamp>(this.isLazy));
165
166 if (this.isLazy) {
167 oldResumableTimestamp = keyMemory.getResumableTimestamp();
168 }
169
170 final Diff<Timestamp> diff = keyMemory.put(tuple, timestamp);
171
172 if (this.isLazy) {
173 newResumableTimestamp = keyMemory.getResumableTimestamp();
174 if (!Objects.equals(oldResumableTimestamp, newResumableTimestamp)) {
175 unregisterFoldingState(oldResumableTimestamp, key);
176 registerFoldingState(newResumableTimestamp, key);
177 }
178 }
179
180 return diff;
181 }
182
183 @Override
184 public Diff<Timestamp> removeWithTimestamp(final Tuple tuple, final Timestamp timestamp) {
185 return removeWithTimestamp(tuple, null, timestamp);
186 }
187
188 @Override
189 public Diff<Timestamp> addWithTimestamp(final Tuple tuple, final Timestamp timestamp) {
190 return addWithTimestamp(tuple, null, timestamp);
191 }
192
193 @Override
194 public boolean isTimely() {
195 return true;
196 }
197
198 protected void registerFoldingState(final Timestamp timestamp, final KeyType key) {
199 if (timestamp != null) {
200 this.foldingStates.compute(timestamp, (k, v) -> {
201 if (v == null) {
202 v = CollectionsFactory.createSet();
203 }
204 v.add(key);
205 return v;
206 });
207 }
208 }
209
210 protected void unregisterFoldingState(final Timestamp timestamp, final KeyType key) {
211 if (timestamp != null) {
212 this.foldingStates.compute(timestamp, (k, v) -> {
213 v.remove(key);
214 return v.isEmpty() ? null : v;
215 });
216 }
217 }
218
219 @Override
220 public Timestamp getResumableTimestamp() {
221 if (this.foldingStates == null || this.foldingStates.isEmpty()) {
222 return null;
223 } else {
224 return this.foldingStates.firstKey();
225 }
226 }
227
228}