aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store/src/main
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-12-13 03:21:58 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-12-13 12:25:02 +0100
commit6ccc179ea305fc27ae121253b1d1f172bad676fd (patch)
tree8c5bb8dd7bf45157cabb57b19d17ce9af11aca5f /subprojects/store/src/main
parentchore(deps): upgrade to yarn canary (diff)
downloadrefinery-6ccc179ea305fc27ae121253b1d1f172bad676fd.tar.gz
refinery-6ccc179ea305fc27ae121253b1d1f172bad676fd.tar.zst
refinery-6ccc179ea305fc27ae121253b1d1f172bad676fd.zip
refactor(store): simplify return types
Prefers sealed non-generic interfaces over wildcard types to avoid confusion about method return types, especially in collections (see SonarQube rule java:S1452).
Diffstat (limited to 'subprojects/store/src/main')
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/AnyVersionedMap.java5
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/Cursor.java29
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/VersionedMap.java20
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreConfiguration.java20
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreImpl.java22
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/internal/MapCursor.java88
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java23
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/internal/VersionedMapImpl.java103
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/Model.java28
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/ModelDiffCursor.java21
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java15
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java41
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java41
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java12
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyAuxiliaryData.java4
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyDataRepresentation.java9
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyRelation.java9
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java2
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java5
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java3
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java10
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java8
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationViewAtom.java8
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/AnyRelationView.java13
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java15
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java16
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java29
27 files changed, 337 insertions, 262 deletions
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/AnyVersionedMap.java b/subprojects/store/src/main/java/tools/refinery/store/map/AnyVersionedMap.java
new file mode 100644
index 00000000..b94b9f38
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/AnyVersionedMap.java
@@ -0,0 +1,5 @@
1package tools.refinery.store.map;
2
3public sealed interface AnyVersionedMap extends Versioned permits VersionedMap {
4 long getSize();
5}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/Cursor.java b/subprojects/store/src/main/java/tools/refinery/store/map/Cursor.java
index 9c465ddc..b420585c 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/Cursor.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/Cursor.java
@@ -1,14 +1,21 @@
1package tools.refinery.store.map; 1package tools.refinery.store.map;
2 2
3import java.util.List; 3import java.util.Set;
4 4
5public interface Cursor<K,V> { 5public interface Cursor<K, V> {
6 public K getKey(); 6 K getKey();
7 public V getValue(); 7
8 public boolean isTerminated(); 8 V getValue();
9 public boolean move(); 9
10 public boolean isDirty(); 10 boolean isTerminated();
11 11
12 @SuppressWarnings("squid:S1452") 12 boolean move();
13 public List<VersionedMap<?,?>> getDependingMaps(); 13
14 default boolean isDirty() {
15 return false;
16 }
17
18 default Set<AnyVersionedMap> getDependingMaps() {
19 return Set.of();
20 }
14} 21}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMap.java b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMap.java
index a8a64d08..31985e94 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMap.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMap.java
@@ -1,13 +1,13 @@
1package tools.refinery.store.map; 1package tools.refinery.store.map;
2 2
3public interface VersionedMap<K,V> extends Versioned{ 3public non-sealed interface VersionedMap<K, V> extends AnyVersionedMap {
4 public V get(K key); 4 V get(K key);
5 public Cursor<K,V> getAll(); 5
6 6 Cursor<K, V> getAll();
7 public V put(K key, V value); 7
8 public void putAll(Cursor<K,V> cursor); 8 V put(K key, V value);
9 9
10 public long getSize(); 10 void putAll(Cursor<K, V> cursor);
11 11
12 public DiffCursor<K,V> getDiffCursor(long state); 12 DiffCursor<K, V> getDiffCursor(long state);
13} 13}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreConfiguration.java b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreConfiguration.java
index 723e5ec4..3856460d 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreConfiguration.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreConfiguration.java
@@ -1,14 +1,14 @@
1package tools.refinery.store.map; 1package tools.refinery.store.map;
2 2
3public class VersionedMapStoreConfiguration { 3public class VersionedMapStoreConfiguration {
4 4
5 public VersionedMapStoreConfiguration() { 5 public VersionedMapStoreConfiguration() {
6 6
7 } 7 }
8 public VersionedMapStoreConfiguration(boolean immutableWhenCommiting, boolean sharedNodeCacheInStore, 8 public VersionedMapStoreConfiguration(boolean immutableWhenCommitting, boolean sharedNodeCacheInStore,
9 boolean sharedNodeCacheInStoreGroups) { 9 boolean sharedNodeCacheInStoreGroups) {
10 super(); 10 super();
11 this.immutableWhenCommiting = immutableWhenCommiting; 11 this.immutableWhenCommitting = immutableWhenCommitting;
12 this.sharedNodeCacheInStore = sharedNodeCacheInStore; 12 this.sharedNodeCacheInStore = sharedNodeCacheInStore;
13 this.sharedNodeCacheInStoreGroups = sharedNodeCacheInStoreGroups; 13 this.sharedNodeCacheInStoreGroups = sharedNodeCacheInStoreGroups;
14 } 14 }
@@ -18,13 +18,13 @@ public class VersionedMapStoreConfiguration {
18 * by releasing immutable nodes, but it may decrease performance by recreating 18 * by releasing immutable nodes, but it may decrease performance by recreating
19 * immutable nodes upon changes (some evidence). 19 * immutable nodes upon changes (some evidence).
20 */ 20 */
21 private boolean immutableWhenCommiting = true; 21 private boolean immutableWhenCommitting = true;
22 public boolean isImmutableWhenCommiting() { 22 public boolean isImmutableWhenCommitting() {
23 return immutableWhenCommiting; 23 return immutableWhenCommitting;
24 } 24 }
25 25
26 /** 26 /**
27 * If true, all subnodes are cached within a {@link VersionedMapStore}. It 27 * If true, all sub-nodes are cached within a {@link VersionedMapStore}. It
28 * decreases the memory requirements. It may increase performance by discovering 28 * decreases the memory requirements. It may increase performance by discovering
29 * existing immutable copy of a node (some evidence). Additional overhead may 29 * existing immutable copy of a node (some evidence). Additional overhead may
30 * decrease performance (no example found). The option permits the efficient 30 * decrease performance (no example found). The option permits the efficient
@@ -34,9 +34,9 @@ public class VersionedMapStoreConfiguration {
34 public boolean isSharedNodeCacheInStore() { 34 public boolean isSharedNodeCacheInStore() {
35 return sharedNodeCacheInStore; 35 return sharedNodeCacheInStore;
36 } 36 }
37 37
38 /** 38 /**
39 * If true, all subnodes are cached within a group of 39 * If true, all sub-nodes are cached within a group of
40 * {@link VersionedMapStoreImpl#createSharedVersionedMapStores(int, ContinousHashProvider, Object, VersionedMapStoreConfiguration)}. 40 * {@link VersionedMapStoreImpl#createSharedVersionedMapStores(int, ContinousHashProvider, Object, VersionedMapStoreConfiguration)}.
41 * If {@link VersionedMapStoreConfiguration#sharedNodeCacheInStore} is 41 * If {@link VersionedMapStoreConfiguration#sharedNodeCacheInStore} is
42 * <code>false</code>, then it has currently no impact. 42 * <code>false</code>, then it has currently no impact.
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreImpl.java b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreImpl.java
index a626a5e8..113874e7 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreImpl.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/VersionedMapStoreImpl.java
@@ -1,22 +1,15 @@
1package tools.refinery.store.map; 1package tools.refinery.store.map;
2 2
3import java.util.ArrayList;
4import java.util.Arrays;
5import java.util.Collections;
6import java.util.HashMap;
7import java.util.HashSet;
8import java.util.List;
9import java.util.Map;
10import java.util.Set;
11
12import tools.refinery.store.map.internal.ImmutableNode; 3import tools.refinery.store.map.internal.ImmutableNode;
13import tools.refinery.store.map.internal.MapDiffCursor; 4import tools.refinery.store.map.internal.MapDiffCursor;
14import tools.refinery.store.map.internal.Node; 5import tools.refinery.store.map.internal.Node;
15import tools.refinery.store.map.internal.VersionedMapImpl; 6import tools.refinery.store.map.internal.VersionedMapImpl;
16 7
8import java.util.*;
9
17public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> { 10public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> {
18 // Configuration 11 // Configuration
19 private final boolean immutableWhenCommiting; 12 private final boolean immutableWhenCommitting;
20 13
21 // Static data 14 // Static data
22 protected final ContinousHashProvider<K> hashProvider; 15 protected final ContinousHashProvider<K> hashProvider;
@@ -29,7 +22,7 @@ public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> {
29 22
30 public VersionedMapStoreImpl(ContinousHashProvider<K> hashProvider, V defaultValue, 23 public VersionedMapStoreImpl(ContinousHashProvider<K> hashProvider, V defaultValue,
31 VersionedMapStoreConfiguration config) { 24 VersionedMapStoreConfiguration config) {
32 this.immutableWhenCommiting = config.isImmutableWhenCommiting(); 25 this.immutableWhenCommitting = config.isImmutableWhenCommitting();
33 this.hashProvider = hashProvider; 26 this.hashProvider = hashProvider;
34 this.defaultValue = defaultValue; 27 this.defaultValue = defaultValue;
35 if (config.isSharedNodeCacheInStore()) { 28 if (config.isSharedNodeCacheInStore()) {
@@ -41,7 +34,7 @@ public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> {
41 34
42 private VersionedMapStoreImpl(ContinousHashProvider<K> hashProvider, V defaultValue, 35 private VersionedMapStoreImpl(ContinousHashProvider<K> hashProvider, V defaultValue,
43 Map<Node<K, V>, ImmutableNode<K, V>> nodeCache, VersionedMapStoreConfiguration config) { 36 Map<Node<K, V>, ImmutableNode<K, V>> nodeCache, VersionedMapStoreConfiguration config) {
44 this.immutableWhenCommiting = config.isImmutableWhenCommiting(); 37 this.immutableWhenCommitting = config.isImmutableWhenCommitting();
45 this.hashProvider = hashProvider; 38 this.hashProvider = hashProvider;
46 this.defaultValue = defaultValue; 39 this.defaultValue = defaultValue;
47 this.nodeCache = nodeCache; 40 this.nodeCache = nodeCache;
@@ -77,7 +70,7 @@ public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> {
77 ContinousHashProvider<K> hashProvider, V defaultValue) { 70 ContinousHashProvider<K> hashProvider, V defaultValue) {
78 return createSharedVersionedMapStores(amount, hashProvider, defaultValue, new VersionedMapStoreConfiguration()); 71 return createSharedVersionedMapStores(amount, hashProvider, defaultValue, new VersionedMapStoreConfiguration());
79 } 72 }
80 73
81 @Override 74 @Override
82 public synchronized Set<Long> getStates() { 75 public synchronized Set<Long> getStates() {
83 return new HashSet<>(states.keySet()); 76 return new HashSet<>(states.keySet());
@@ -93,7 +86,6 @@ public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> {
93 ImmutableNode<K, V> data = revert(state); 86 ImmutableNode<K, V> data = revert(state);
94 return new VersionedMapImpl<>(this, hashProvider, defaultValue, data); 87 return new VersionedMapImpl<>(this, hashProvider, defaultValue, data);
95 } 88 }
96
97 89
98 public synchronized ImmutableNode<K, V> revert(long state) { 90 public synchronized ImmutableNode<K, V> revert(long state) {
99 if (states.containsKey(state)) { 91 if (states.containsKey(state)) {
@@ -118,7 +110,7 @@ public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> {
118 throw new IllegalStateException("Map store run out of Id-s"); 110 throw new IllegalStateException("Map store run out of Id-s");
119 long id = nextID++; 111 long id = nextID++;
120 this.states.put(id, immutable); 112 this.states.put(id, immutable);
121 if (this.immutableWhenCommiting) { 113 if (this.immutableWhenCommitting) {
122 mapToUpdateRoot.setRoot(immutable); 114 mapToUpdateRoot.setRoot(immutable);
123 } 115 }
124 return id; 116 return id;
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapCursor.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapCursor.java
index b90f5b71..1698830f 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapCursor.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapCursor.java
@@ -1,128 +1,136 @@
1package tools.refinery.store.map.internal; 1package tools.refinery.store.map.internal;
2 2
3import tools.refinery.store.map.AnyVersionedMap;
4import tools.refinery.store.map.Cursor;
5import tools.refinery.store.map.VersionedMap;
6
3import java.util.ArrayDeque; 7import java.util.ArrayDeque;
4import java.util.ConcurrentModificationException; 8import java.util.ConcurrentModificationException;
5import java.util.Iterator; 9import java.util.Iterator;
6import java.util.List; 10import java.util.Set;
7
8import tools.refinery.store.map.Cursor;
9import tools.refinery.store.map.VersionedMap;
10 11
11public class MapCursor<K,V> implements Cursor<K,V> { 12public class MapCursor<K, V> implements Cursor<K, V> {
12 // Constants 13 // Constants
13 static final int INDEX_START = -1; 14 static final int INDEX_START = -1;
14 static final int INDEX_FINISH = -2; 15 static final int INDEX_FINISH = -2;
15 16
16 // Tree stack 17 // Tree stack
17 ArrayDeque<Node<K,V>> nodeStack; 18 ArrayDeque<Node<K, V>> nodeStack;
18 ArrayDeque<Integer> nodeIndexStack; 19 ArrayDeque<Integer> nodeIndexStack;
19 int dataIndex; 20 int dataIndex;
20 21
21 // Values 22 // Values
22 K key; 23 K key;
23 V value; 24 V value;
24 25
25 // Hash code for checking concurrent modifications 26 // Hash code for checking concurrent modifications
26 final VersionedMap<K,V> map; 27 final VersionedMap<K, V> map;
27 final int creationHash; 28 final int creationHash;
28 29
29 public MapCursor(Node<K, V> root, VersionedMap<K,V> map) { 30 public MapCursor(Node<K, V> root, VersionedMap<K, V> map) {
30 // Initializing tree stack 31 // Initializing tree stack
31 super(); 32 super();
32 this.nodeStack = new ArrayDeque<>(); 33 this.nodeStack = new ArrayDeque<>();
33 this.nodeIndexStack = new ArrayDeque<>(); 34 this.nodeIndexStack = new ArrayDeque<>();
34 if(root != null) { 35 if (root != null) {
35 this.nodeStack.add(root); 36 this.nodeStack.add(root);
36 this.nodeIndexStack.push(INDEX_START); 37 this.nodeIndexStack.push(INDEX_START);
37 } 38 }
38 39
39 this.dataIndex = INDEX_START; 40 this.dataIndex = INDEX_START;
40 41
41 // Initializing cache 42 // Initializing cache
42 this.key = null; 43 this.key = null;
43 this.value = null; 44 this.value = null;
44 45
45 // Initializing state 46 // Initializing state
46 this.map=map; 47 this.map = map;
47 this.creationHash = map.hashCode(); 48 this.creationHash = map.hashCode();
48 } 49 }
49 50
50 public K getKey() { 51 public K getKey() {
51 return key; 52 return key;
52 } 53 }
53 54
54 public V getValue() { 55 public V getValue() {
55 return value; 56 return value;
56 } 57 }
57 58
58 public boolean isTerminated() { 59 public boolean isTerminated() {
59 return this.nodeStack.isEmpty(); 60 return this.nodeStack.isEmpty();
60 } 61 }
61 62
62 public boolean move() { 63 public boolean move() {
63 if(isDirty()) { 64 if (isDirty()) {
64 throw new ConcurrentModificationException(); 65 throw new ConcurrentModificationException();
65 } 66 }
66 if(!isTerminated()) { 67 if (!isTerminated()) {
67 boolean result = this.nodeStack.peek().moveToNext(this); 68 var node = this.nodeStack.peek();
68 if(this.nodeIndexStack.size() != this.nodeStack.size()) { 69 if (node == null) {
70 throw new IllegalStateException("Cursor is not terminated but the current node is missing");
71 }
72 boolean result = node.moveToNext(this);
73 if (this.nodeIndexStack.size() != this.nodeStack.size()) {
69 throw new IllegalArgumentException("Node stack is corrupted by illegal moves!"); 74 throw new IllegalArgumentException("Node stack is corrupted by illegal moves!");
70 } 75 }
71 return result; 76 return result;
72 } 77 }
73 return false; 78 return false;
74 } 79 }
80
75 public boolean skipCurrentNode() { 81 public boolean skipCurrentNode() {
76 nodeStack.pop(); 82 nodeStack.pop();
77 nodeIndexStack.pop(); 83 nodeIndexStack.pop();
78 dataIndex = INDEX_FINISH; 84 dataIndex = INDEX_FINISH;
79 return move(); 85 return move();
80 } 86 }
87
81 @Override 88 @Override
82 public boolean isDirty() { 89 public boolean isDirty() {
83 return this.map.hashCode() != this.creationHash; 90 return this.map.hashCode() != this.creationHash;
84 } 91 }
92
85 @Override 93 @Override
86 public List<VersionedMap<?, ?>> getDependingMaps() { 94 public Set<AnyVersionedMap> getDependingMaps() {
87 return List.of(this.map); 95 return Set.of(this.map);
88 } 96 }
89 97
90 public static <K,V> boolean sameSubnode(MapCursor<K,V> cursor1, MapCursor<K,V> cursor2) { 98 public static <K, V> boolean sameSubnode(MapCursor<K, V> cursor1, MapCursor<K, V> cursor2) {
91 Node<K, V> nodeOfCursor1 = cursor1.nodeStack.peek(); 99 Node<K, V> nodeOfCursor1 = cursor1.nodeStack.peek();
92 Node<K, V> nodeOfCursor2 = cursor2.nodeStack.peek(); 100 Node<K, V> nodeOfCursor2 = cursor2.nodeStack.peek();
93 if(nodeOfCursor1 != null && nodeOfCursor2 != null) { 101 if (nodeOfCursor1 != null && nodeOfCursor2 != null) {
94 return nodeOfCursor1.equals(nodeOfCursor2); 102 return nodeOfCursor1.equals(nodeOfCursor2);
95 } else { 103 } else {
96 return false; 104 return false;
97 } 105 }
98 } 106 }
99 107
100 /** 108 /**
101 *
102 * @param <K> 109 * @param <K>
103 * @param <V> 110 * @param <V>
104 * @param cursor1 111 * @param cursor1
105 * @param cursor2 112 * @param cursor2
106 * @return Positive number if cursor 1 is behind, negative number if cursor 2 is behind, and 0 if they are at the same position. 113 * @return Positive number if cursor 1 is behind, negative number if cursor 2 is behind, and 0 if they are at the
114 * same position.
107 */ 115 */
108 public static <K,V> int compare(MapCursor<K,V> cursor1, MapCursor<K,V> cursor2) { 116 public static <K, V> int compare(MapCursor<K, V> cursor1, MapCursor<K, V> cursor2) {
109 // two cursors are equally deep 117 // two cursors are equally deep
110 Iterator<Integer> stack1 = cursor1.nodeIndexStack.descendingIterator(); 118 Iterator<Integer> stack1 = cursor1.nodeIndexStack.descendingIterator();
111 Iterator<Integer> stack2 = cursor2.nodeIndexStack.descendingIterator(); 119 Iterator<Integer> stack2 = cursor2.nodeIndexStack.descendingIterator();
112 if(stack1.hasNext()) { 120 if (stack1.hasNext()) {
113 if(!stack2.hasNext()) { 121 if (!stack2.hasNext()) {
114 // stack 2 has no more element, thus stack 1 is deeper 122 // stack 2 has no more element, thus stack 1 is deeper
115 return 1; 123 return 1;
116 } 124 }
117 int val1 = stack1.next(); 125 int val1 = stack1.next();
118 int val2 = stack2.next(); 126 int val2 = stack2.next();
119 if(val1 < val2) { 127 if (val1 < val2) {
120 return -1; 128 return -1;
121 } else if(val2 < val1) { 129 } else if (val2 < val1) {
122 return 1; 130 return 1;
123 } 131 }
124 } 132 }
125 if(stack2.hasNext()) { 133 if (stack2.hasNext()) {
126 // stack 2 has more element, thus stack 2 is deeper 134 // stack 2 has more element, thus stack 2 is deeper
127 return 1; 135 return 1;
128 } 136 }
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java
index a4ca813c..9cd78113 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java
@@ -1,12 +1,13 @@
1package tools.refinery.store.map.internal; 1package tools.refinery.store.map.internal;
2 2
3import java.util.List; 3import tools.refinery.store.map.AnyVersionedMap;
4import java.util.stream.Stream;
5
6import tools.refinery.store.map.ContinousHashProvider; 4import tools.refinery.store.map.ContinousHashProvider;
7import tools.refinery.store.map.Cursor; 5import tools.refinery.store.map.Cursor;
8import tools.refinery.store.map.DiffCursor; 6import tools.refinery.store.map.DiffCursor;
9import tools.refinery.store.map.VersionedMap; 7
8import java.util.Set;
9import java.util.stream.Collectors;
10import java.util.stream.Stream;
10 11
11/** 12/**
12 * A cursor representing the difference between two states of a map. 13 * A cursor representing the difference between two states of a map.
@@ -18,10 +19,10 @@ public class MapDiffCursor<K, V> implements DiffCursor<K, V>, Cursor<K, V> {
18 /** 19 /**
19 * Default nodeId representing missing elements. 20 * Default nodeId representing missing elements.
20 */ 21 */
21 private V defaultValue; 22 private final V defaultValue;
22 private MapCursor<K, V> cursor1; 23 private final MapCursor<K, V> cursor1;
23 private MapCursor<K, V> cursor2; 24 private final MapCursor<K, V> cursor2;
24 private ContinousHashProvider<? super K> hashProvider; 25 private final ContinousHashProvider<? super K> hashProvider;
25 26
26 // Values 27 // Values
27 private K key; 28 private K key;
@@ -75,8 +76,10 @@ public class MapDiffCursor<K, V> implements DiffCursor<K, V>, Cursor<K, V> {
75 } 76 }
76 77
77 @Override 78 @Override
78 public List<VersionedMap<?, ?>> getDependingMaps() { 79 public Set<AnyVersionedMap> getDependingMaps() {
79 return Stream.concat(cursor1.getDependingMaps().stream(), cursor2.getDependingMaps().stream()).toList(); 80 return Stream.concat(cursor1.getDependingMaps().stream(), cursor2.getDependingMaps().stream())
81 .map(AnyVersionedMap.class::cast)
82 .collect(Collectors.toUnmodifiableSet());
80 } 83 }
81 84
82 protected void updateState() { 85 protected void updateState() {
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/VersionedMapImpl.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/VersionedMapImpl.java
index 346fe596..866e7b33 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/map/internal/VersionedMapImpl.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/VersionedMapImpl.java
@@ -1,61 +1,59 @@
1package tools.refinery.store.map.internal; 1package tools.refinery.store.map.internal;
2 2
3import tools.refinery.store.map.*;
4
3import java.util.Iterator; 5import java.util.Iterator;
4import java.util.LinkedList; 6import java.util.LinkedList;
5import java.util.List; 7import java.util.List;
6 8
7import tools.refinery.store.map.ContinousHashProvider;
8import tools.refinery.store.map.Cursor;
9import tools.refinery.store.map.DiffCursor;
10import tools.refinery.store.map.VersionedMap;
11import tools.refinery.store.map.VersionedMapStoreImpl;
12
13/** 9/**
14 * Not threadSafe in itself 10 * Not threadSafe in itself
15 * @author Oszkar Semerath
16 * 11 *
17 * @param <K> 12 * @param <K>
18 * @param <V> 13 * @param <V>
14 * @author Oszkar Semerath
19 */ 15 */
20public class VersionedMapImpl<K,V> implements VersionedMap<K,V>{ 16public class VersionedMapImpl<K, V> implements VersionedMap<K, V> {
21 protected final VersionedMapStoreImpl<K,V> store; 17 protected final VersionedMapStoreImpl<K, V> store;
22 18
23 protected final ContinousHashProvider<K> hashProvider; 19 protected final ContinousHashProvider<K> hashProvider;
20
24 protected final V defaultValue; 21 protected final V defaultValue;
25 protected Node<K,V> root; 22 protected Node<K, V> root;
26 23
27 private OldValueBox<V> oldValueBox = new OldValueBox<>(); 24 private final OldValueBox<V> oldValueBox = new OldValueBox<>();
28 25
29 public VersionedMapImpl( 26 public VersionedMapImpl(
30 VersionedMapStoreImpl<K,V> store, 27 VersionedMapStoreImpl<K, V> store,
31 ContinousHashProvider<K> hashProvider, 28 ContinousHashProvider<K> hashProvider,
32 V defaultValue) 29 V defaultValue) {
33 {
34 this.store = store; 30 this.store = store;
35 this.hashProvider = hashProvider; 31 this.hashProvider = hashProvider;
36 this.defaultValue = defaultValue; 32 this.defaultValue = defaultValue;
37 this.root = null; 33 this.root = null;
38 } 34 }
35
39 public VersionedMapImpl( 36 public VersionedMapImpl(
40 VersionedMapStoreImpl<K,V> store, 37 VersionedMapStoreImpl<K, V> store,
41 ContinousHashProvider<K> hashProvider, 38 ContinousHashProvider<K> hashProvider,
42 V defaultValue, Node<K,V> data) 39 V defaultValue, Node<K, V> data) {
43 {
44 this.store = store; 40 this.store = store;
45 this.hashProvider = hashProvider; 41 this.hashProvider = hashProvider;
46 this.defaultValue = defaultValue; 42 this.defaultValue = defaultValue;
47 this.root = data; 43 this.root = data;
48 } 44 }
49 45
50 public V getDefaultValue() { 46 public V getDefaultValue() {
51 return defaultValue; 47 return defaultValue;
52 } 48 }
49
53 public ContinousHashProvider<K> getHashProvider() { 50 public ContinousHashProvider<K> getHashProvider() {
54 return hashProvider; 51 return hashProvider;
55 } 52 }
53
56 @Override 54 @Override
57 public V put(K key, V value) { 55 public V put(K key, V value) {
58 if(root!=null) { 56 if (root != null) {
59 root = root.putValue(key, value, oldValueBox, hashProvider, defaultValue, hashProvider.getHash(key, 0), 0); 57 root = root.putValue(key, value, oldValueBox, hashProvider, defaultValue, hashProvider.getHash(key, 0), 0);
60 return oldValueBox.getOldValue(); 58 return oldValueBox.getOldValue();
61 } else { 59 } else {
@@ -63,39 +61,40 @@ public class VersionedMapImpl<K,V> implements VersionedMap<K,V>{
63 return defaultValue; 61 return defaultValue;
64 } 62 }
65 } 63 }
66 64
67 @Override 65 @Override
68 public void putAll(Cursor<K, V> cursor) { 66 public void putAll(Cursor<K, V> cursor) {
69 if(cursor.getDependingMaps().contains(this)) { 67 if (cursor.getDependingMaps().contains(this)) {
70 List<K> keys = new LinkedList<>(); 68 List<K> keys = new LinkedList<>();
71 List<V> values = new LinkedList<>(); 69 List<V> values = new LinkedList<>();
72 while(cursor.move()) { 70 while (cursor.move()) {
73 keys.add(cursor.getKey()); 71 keys.add(cursor.getKey());
74 values.add(cursor.getValue()); 72 values.add(cursor.getValue());
75 } 73 }
76 Iterator<K> keyIterator = keys.iterator(); 74 Iterator<K> keyIterator = keys.iterator();
77 Iterator<V> valueIterator = values.iterator(); 75 Iterator<V> valueIterator = values.iterator();
78 while(keyIterator.hasNext()) { 76 while (keyIterator.hasNext()) {
79 this.put(keyIterator.next(), valueIterator.next()); 77 this.put(keyIterator.next(), valueIterator.next());
80 } 78 }
81 } else { 79 } else {
82 while(cursor.move()) { 80 while (cursor.move()) {
83 this.put(cursor.getKey(), cursor.getValue()); 81 this.put(cursor.getKey(), cursor.getValue());
84 } 82 }
85 } 83 }
86 } 84 }
87 85
88 @Override 86 @Override
89 public V get(K key) { 87 public V get(K key) {
90 if(root!=null) { 88 if (root != null) {
91 return root.getValue(key, hashProvider, defaultValue, hashProvider.getHash(key, 0), 0); 89 return root.getValue(key, hashProvider, defaultValue, hashProvider.getHash(key, 0), 0);
92 } else { 90 } else {
93 return defaultValue; 91 return defaultValue;
94 } 92 }
95 } 93 }
94
96 @Override 95 @Override
97 public long getSize() { 96 public long getSize() {
98 if(root == null) { 97 if (root == null) {
99 return 0; 98 return 0;
100 } else { 99 } else {
101 return root.getSize(); 100 return root.getSize();
@@ -104,22 +103,24 @@ public class VersionedMapImpl<K,V> implements VersionedMap<K,V>{
104 103
105 @Override 104 @Override
106 public Cursor<K, V> getAll() { 105 public Cursor<K, V> getAll() {
107 return new MapCursor<>(this.root,this); 106 return new MapCursor<>(this.root, this);
108 } 107 }
108
109 @Override 109 @Override
110 public DiffCursor<K, V> getDiffCursor(long toVersion) { 110 public DiffCursor<K, V> getDiffCursor(long toVersion) {
111 Cursor<K, V> fromCursor = this.getAll(); 111 Cursor<K, V> fromCursor = this.getAll();
112 VersionedMap<K, V> toMap = this.store.createMap(toVersion); 112 VersionedMap<K, V> toMap = this.store.createMap(toVersion);
113 Cursor<K, V> toCursor = toMap.getAll(); 113 Cursor<K, V> toCursor = toMap.getAll();
114 return new MapDiffCursor<>(this.hashProvider,this.defaultValue, fromCursor, toCursor); 114 return new MapDiffCursor<>(this.hashProvider, this.defaultValue, fromCursor, toCursor);
115 115
116 } 116 }
117 117
118 118
119 @Override 119 @Override
120 public long commit() { 120 public long commit() {
121 return this.store.commit(root,this); 121 return this.store.commit(root, this);
122 } 122 }
123
123 public void setRoot(Node<K, V> root) { 124 public void setRoot(Node<K, V> root) {
124 this.root = root; 125 this.root = root;
125 } 126 }
@@ -128,44 +129,20 @@ public class VersionedMapImpl<K,V> implements VersionedMap<K,V>{
128 public void restore(long state) { 129 public void restore(long state) {
129 root = this.store.revert(state); 130 root = this.store.revert(state);
130 } 131 }
131 132
132 @Override
133 public int hashCode() {
134 final int prime = 31;
135 int result = 1;
136 result = prime * result + ((root == null) ? 0 : root.hashCode());
137 return result;
138 }
139
140 @Override
141 public boolean equals(Object obj) {
142 if (this == obj)
143 return true;
144 if (obj == null)
145 return false;
146 if (getClass() != obj.getClass())
147 return false;
148 VersionedMapImpl<?,?> other = (VersionedMapImpl<?,?>) obj;
149 if (root == null) {
150 if (other.root != null)
151 return false;
152 } else if (!root.equals(other.root))
153 return false;
154 return true;
155 }
156 public void prettyPrint() { 133 public void prettyPrint() {
157 StringBuilder s = new StringBuilder(); 134 StringBuilder s = new StringBuilder();
158 if(this.root != null) { 135 if (this.root != null) {
159 this.root.prettyPrint(s, 0, -1); 136 this.root.prettyPrint(s, 0, -1);
160 System.out.println(s.toString()); 137 System.out.println(s.toString());
161 } else { 138 } else {
162 System.out.println("empty tree"); 139 System.out.println("empty tree");
163 } 140 }
164 } 141 }
142
165 public void checkIntegrity() { 143 public void checkIntegrity() {
166 if(this.root != null) { 144 if (this.root != null) {
167 this.root.checkIntegrity(hashProvider, defaultValue, 0); 145 this.root.checkIntegrity(hashProvider, defaultValue, 0);
168 } 146 }
169 } 147 }
170
171} 148}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/Model.java b/subprojects/store/src/main/java/tools/refinery/store/model/Model.java
index a42d711a..69f57389 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/Model.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/Model.java
@@ -1,20 +1,24 @@
1package tools.refinery.store.model; 1package tools.refinery.store.model;
2 2
3import java.util.Set;
4
5import tools.refinery.store.map.Cursor; 3import tools.refinery.store.map.Cursor;
6import tools.refinery.store.map.Versioned; 4import tools.refinery.store.map.Versioned;
5import tools.refinery.store.model.representation.AnyDataRepresentation;
7import tools.refinery.store.model.representation.DataRepresentation; 6import tools.refinery.store.model.representation.DataRepresentation;
8 7
9public interface Model extends Versioned{ 8import java.util.Set;
10 @SuppressWarnings("squid:S1452") 9
11 Set<DataRepresentation<?, ?>> getDataRepresentations(); 10public interface Model extends Versioned {
12 11 Set<AnyDataRepresentation> getDataRepresentations();
13 <K,V> V get(DataRepresentation<K,V> representation, K key); 12
14 <K,V> Cursor<K,V> getAll(DataRepresentation<K,V> representation); 13 <K, V> V get(DataRepresentation<K, V> representation, K key);
15 <K,V> V put(DataRepresentation<K,V> representation, K key, V value); 14
16 <K,V> void putAll(DataRepresentation<K,V> representation, Cursor<K,V> cursor); 15 <K, V> Cursor<K, V> getAll(DataRepresentation<K, V> representation);
17 <K,V> long getSize(DataRepresentation<K,V> representation); 16
18 17 <K, V> V put(DataRepresentation<K, V> representation, K key, V value);
18
19 <K, V> void putAll(DataRepresentation<K, V> representation, Cursor<K, V> cursor);
20
21 long getSize(AnyDataRepresentation representation);
22
19 ModelDiffCursor getDiffCursor(long to); 23 ModelDiffCursor getDiffCursor(long to);
20} 24}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/ModelDiffCursor.java b/subprojects/store/src/main/java/tools/refinery/store/model/ModelDiffCursor.java
index 91990fa6..d5bb541b 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/ModelDiffCursor.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/ModelDiffCursor.java
@@ -1,26 +1,27 @@
1package tools.refinery.store.model; 1package tools.refinery.store.model;
2 2
3import java.util.Map;
4
5import tools.refinery.store.map.Cursor; 3import tools.refinery.store.map.Cursor;
6import tools.refinery.store.map.DiffCursor; 4import tools.refinery.store.map.DiffCursor;
5import tools.refinery.store.model.representation.AnyDataRepresentation;
7import tools.refinery.store.model.representation.DataRepresentation; 6import tools.refinery.store.model.representation.DataRepresentation;
8 7
8import java.util.Map;
9
9public class ModelDiffCursor { 10public class ModelDiffCursor {
10 final Map<DataRepresentation<?, ?>,DiffCursor<?,?>> diffcursors; 11 final Map<AnyDataRepresentation, DiffCursor<?, ?>> diffCursors;
11 12
12 public ModelDiffCursor(Map<DataRepresentation<?, ?>, DiffCursor<?, ?>> diffcursors) { 13 public ModelDiffCursor(Map<AnyDataRepresentation, DiffCursor<?, ?>> diffCursors) {
13 super(); 14 super();
14 this.diffcursors = diffcursors; 15 this.diffCursors = diffCursors;
15 } 16 }
16 17
17 @SuppressWarnings("unchecked") 18 @SuppressWarnings("unchecked")
18 public <K,V> DiffCursor<K,V> getCursor(DataRepresentation<K, V> representation) { 19 public <K, V> DiffCursor<K, V> getCursor(DataRepresentation<K, V> representation) {
19 Cursor<?, ?> cursor = diffcursors.get(representation); 20 Cursor<?, ?> cursor = diffCursors.get(representation);
20 if(cursor != null) { 21 if (cursor != null) {
21 return (DiffCursor<K, V>) cursor; 22 return (DiffCursor<K, V>) cursor;
22 } else { 23 } else {
23 throw new IllegalArgumentException("ModelCursor does not contain cursor for representation "+representation); 24 throw new IllegalArgumentException("ModelCursor does not contain cursor for representation " + representation);
24 } 25 }
25 } 26 }
26} 27}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java
index 682a0e78..84b67765 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStore.java
@@ -1,16 +1,17 @@
1package tools.refinery.store.model; 1package tools.refinery.store.model;
2 2
3import java.util.Set; 3import tools.refinery.store.model.representation.AnyDataRepresentation;
4 4
5import tools.refinery.store.model.representation.DataRepresentation; 5import java.util.Set;
6 6
7public interface ModelStore { 7public interface ModelStore {
8 @SuppressWarnings("squid:S1452") 8 Set<AnyDataRepresentation> getDataRepresentations();
9 Set<DataRepresentation<?, ?>> getDataRepresentations(); 9
10
11 Model createModel(); 10 Model createModel();
11
12 Model createModel(long state); 12 Model createModel(long state);
13 13
14 Set<Long> getStates(); 14 Set<Long> getStates();
15
15 ModelDiffCursor getDiffCursor(long from, long to); 16 ModelDiffCursor getDiffCursor(long from, long to);
16} \ No newline at end of file 17}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java
index d08cf0f8..2f73a0e5 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java
@@ -3,6 +3,7 @@ package tools.refinery.store.model;
3import tools.refinery.store.map.*; 3import tools.refinery.store.map.*;
4import tools.refinery.store.model.internal.ModelImpl; 4import tools.refinery.store.model.internal.ModelImpl;
5import tools.refinery.store.model.internal.SimilarRelationEquivalenceClass; 5import tools.refinery.store.model.internal.SimilarRelationEquivalenceClass;
6import tools.refinery.store.model.representation.AnyDataRepresentation;
6import tools.refinery.store.model.representation.AuxiliaryData; 7import tools.refinery.store.model.representation.AuxiliaryData;
7import tools.refinery.store.model.representation.DataRepresentation; 8import tools.refinery.store.model.representation.DataRepresentation;
8import tools.refinery.store.model.representation.Relation; 9import tools.refinery.store.model.representation.Relation;
@@ -13,26 +14,26 @@ import java.util.Map.Entry;
13 14
14public class ModelStoreImpl implements ModelStore { 15public class ModelStoreImpl implements ModelStore {
15 16
16 private final Map<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> stores; 17 private final Map<AnyDataRepresentation, VersionedMapStore<?, ?>> stores;
17 18
18 public ModelStoreImpl(Set<DataRepresentation<?, ?>> dataRepresentations) { 19 public ModelStoreImpl(Set<AnyDataRepresentation> dataRepresentations) {
19 stores = initStores(dataRepresentations); 20 stores = initStores(dataRepresentations);
20 } 21 }
21 22
22 private Map<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> initStores( 23 private Map<AnyDataRepresentation, VersionedMapStore<?, ?>> initStores(
23 Set<DataRepresentation<?, ?>> dataRepresentations) { 24 Set<AnyDataRepresentation> dataRepresentations) {
24 Map<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> result = new HashMap<>(); 25 Map<AnyDataRepresentation, VersionedMapStore<?, ?>> result = new HashMap<>();
25 26
26 Map<SimilarRelationEquivalenceClass, List<Relation<?>>> symbolRepresentationsPerHashPerArity = new HashMap<>(); 27 Map<SimilarRelationEquivalenceClass, List<Relation<?>>> symbolRepresentationsPerHashPerArity = new HashMap<>();
27 28
28 for (DataRepresentation<?, ?> dataRepresentation : dataRepresentations) { 29 for (AnyDataRepresentation dataRepresentation : dataRepresentations) {
29 if (dataRepresentation instanceof Relation<?> symbolRepresentation) { 30 if (dataRepresentation instanceof Relation<?> symbolRepresentation) {
30 addOrCreate(symbolRepresentationsPerHashPerArity, 31 addOrCreate(symbolRepresentationsPerHashPerArity,
31 new SimilarRelationEquivalenceClass(symbolRepresentation), symbolRepresentation); 32 new SimilarRelationEquivalenceClass(symbolRepresentation), symbolRepresentation);
32 } else if (dataRepresentation instanceof AuxiliaryData<?, ?>) { 33 } else if (dataRepresentation instanceof AuxiliaryData<?, ?> auxiliaryData) {
33 VersionedMapStoreImpl<?, ?> store = new VersionedMapStoreImpl<>(dataRepresentation.getHashProvider(), 34 VersionedMapStoreImpl<?, ?> store = new VersionedMapStoreImpl<>(auxiliaryData.getHashProvider(),
34 dataRepresentation.getDefaultValue()); 35 auxiliaryData.getDefaultValue());
35 result.put(dataRepresentation, store); 36 result.put(auxiliaryData, store);
36 } else { 37 } else {
37 throw new UnsupportedOperationException( 38 throw new UnsupportedOperationException(
38 "Model store does not have strategy to use " + dataRepresentation.getClass() + "!"); 39 "Model store does not have strategy to use " + dataRepresentation.getClass() + "!");
@@ -45,7 +46,7 @@ public class ModelStoreImpl implements ModelStore {
45 return result; 46 return result;
46 } 47 }
47 48
48 private void initRepresentationGroup(Map<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> result, 49 private void initRepresentationGroup(Map<AnyDataRepresentation, VersionedMapStore<?, ?>> result,
49 List<Relation<?>> symbolGroup) { 50 List<Relation<?>> symbolGroup) {
50 final ContinousHashProvider<Tuple> hashProvider = symbolGroup.get(0).getHashProvider(); 51 final ContinousHashProvider<Tuple> hashProvider = symbolGroup.get(0).getHashProvider();
51 final Object defaultValue = symbolGroup.get(0).getDefaultValue(); 52 final Object defaultValue = symbolGroup.get(0).getDefaultValue();
@@ -70,14 +71,14 @@ public class ModelStoreImpl implements ModelStore {
70 } 71 }
71 72
72 @Override 73 @Override
73 public Set<DataRepresentation<?, ?>> getDataRepresentations() { 74 public Set<AnyDataRepresentation> getDataRepresentations() {
74 return this.stores.keySet(); 75 return this.stores.keySet();
75 } 76 }
76 77
77 @Override 78 @Override
78 public ModelImpl createModel() { 79 public ModelImpl createModel() {
79 Map<DataRepresentation<?, ?>, VersionedMap<?, ?>> maps = new HashMap<>(); 80 Map<AnyDataRepresentation, VersionedMap<?, ?>> maps = new HashMap<>();
80 for (Entry<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> entry : this.stores.entrySet()) { 81 for (var entry : this.stores.entrySet()) {
81 maps.put(entry.getKey(), entry.getValue().createMap()); 82 maps.put(entry.getKey(), entry.getValue().createMap());
82 } 83 }
83 return new ModelImpl(this, maps); 84 return new ModelImpl(this, maps);
@@ -85,8 +86,8 @@ public class ModelStoreImpl implements ModelStore {
85 86
86 @Override 87 @Override
87 public synchronized ModelImpl createModel(long state) { 88 public synchronized ModelImpl createModel(long state) {
88 Map<DataRepresentation<?, ?>, VersionedMap<?, ?>> maps = new HashMap<>(); 89 Map<AnyDataRepresentation, VersionedMap<?, ?>> maps = new HashMap<>();
89 for (Entry<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> entry : this.stores.entrySet()) { 90 for (var entry : this.stores.entrySet()) {
90 maps.put(entry.getKey(), entry.getValue().createMap(state)); 91 maps.put(entry.getKey(), entry.getValue().createMap(state));
91 } 92 }
92 return new ModelImpl(this, maps); 93 return new ModelImpl(this, maps);
@@ -103,10 +104,10 @@ public class ModelStoreImpl implements ModelStore {
103 104
104 @Override 105 @Override
105 public synchronized ModelDiffCursor getDiffCursor(long from, long to) { 106 public synchronized ModelDiffCursor getDiffCursor(long from, long to) {
106 Map<DataRepresentation<?, ?>, DiffCursor<?, ?>> diffcursors = new HashMap<>(); 107 Map<AnyDataRepresentation, DiffCursor<?, ?>> diffcursors = new HashMap<>();
107 for (Entry<DataRepresentation<?, ?>, VersionedMapStore<?, ?>> entry : stores.entrySet()) { 108 for (var entry : stores.entrySet()) {
108 DataRepresentation<?, ?> representation = entry.getKey(); 109 var representation = entry.getKey();
109 DiffCursor<?, ?> diffCursor = entry.getValue().getDiffCursor(from, to); 110 var diffCursor = entry.getValue().getDiffCursor(from, to);
110 diffcursors.put(representation, diffCursor); 111 diffcursors.put(representation, diffCursor);
111 } 112 }
112 return new ModelDiffCursor(diffcursors); 113 return new ModelDiffCursor(diffcursors);
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java
index 2a5f2925..795a891b 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/internal/ModelImpl.java
@@ -1,9 +1,5 @@
1package tools.refinery.store.model.internal; 1package tools.refinery.store.model.internal;
2 2
3import java.util.HashMap;
4import java.util.Map;
5import java.util.Set;
6
7import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
8import tools.refinery.store.map.Cursor; 4import tools.refinery.store.map.Cursor;
9import tools.refinery.store.map.DiffCursor; 5import tools.refinery.store.map.DiffCursor;
@@ -12,31 +8,41 @@ import tools.refinery.store.map.internal.MapDiffCursor;
12import tools.refinery.store.model.Model; 8import tools.refinery.store.model.Model;
13import tools.refinery.store.model.ModelDiffCursor; 9import tools.refinery.store.model.ModelDiffCursor;
14import tools.refinery.store.model.ModelStore; 10import tools.refinery.store.model.ModelStore;
11import tools.refinery.store.model.representation.AnyDataRepresentation;
15import tools.refinery.store.model.representation.DataRepresentation; 12import tools.refinery.store.model.representation.DataRepresentation;
16 13
14import java.util.HashMap;
15import java.util.Map;
16import java.util.Set;
17
17public class ModelImpl implements Model { 18public class ModelImpl implements Model {
18 private final ModelStore store; 19 private final ModelStore store;
19 private final Map<DataRepresentation<?, ?>, VersionedMap<?, ?>> maps;
20 20
21 public ModelImpl(ModelStore store, Map<DataRepresentation<?, ?>, VersionedMap<?, ?>> maps) { 21 private final Map<AnyDataRepresentation, VersionedMap<?, ?>> maps;
22
23 public ModelImpl(ModelStore store, Map<AnyDataRepresentation, VersionedMap<?, ?>> maps) {
22 this.store = store; 24 this.store = store;
23 this.maps = maps; 25 this.maps = maps;
24 } 26 }
25 27
26 @Override 28 @Override
27 public Set<DataRepresentation<?, ?>> getDataRepresentations() { 29 public Set<AnyDataRepresentation> getDataRepresentations() {
28 return maps.keySet(); 30 return maps.keySet();
29 } 31 }
30 32
31 @SuppressWarnings("unchecked") 33 private VersionedMap<?, ?> getMap(AnyDataRepresentation representation) {
32 private <K, V> VersionedMap<K, V> getMap(DataRepresentation<K, V> representation) {
33 if (maps.containsKey(representation)) { 34 if (maps.containsKey(representation)) {
34 return (VersionedMap<K, V>) maps.get(representation); 35 return maps.get(representation);
35 } else { 36 } else {
36 throw new IllegalArgumentException("Model does have representation " + representation); 37 throw new IllegalArgumentException("Model does have representation " + representation);
37 } 38 }
38 } 39 }
39 40
41 @SuppressWarnings("unchecked")
42 private <K, V> VersionedMap<K, V> getMap(DataRepresentation<K, V> representation) {
43 return (VersionedMap<K, V>) maps.get(representation);
44 }
45
40 private <K, V> VersionedMap<K, V> getMapValidateKey(DataRepresentation<K, V> representation, K key) { 46 private <K, V> VersionedMap<K, V> getMapValidateKey(DataRepresentation<K, V> representation, K key) {
41 if (representation.isValidKey(key)) { 47 if (representation.isValidKey(key)) {
42 return getMap(representation); 48 return getMap(representation);
@@ -67,17 +73,18 @@ public class ModelImpl implements Model {
67 } 73 }
68 74
69 @Override 75 @Override
70 public <K, V> long getSize(DataRepresentation<K, V> representation) { 76 public long getSize(AnyDataRepresentation representation) {
71 return getMap(representation).getSize(); 77 return getMap(representation).getSize();
72 } 78 }
73 79
74 @Override 80 @Override
75 public ModelDiffCursor getDiffCursor(long to) { 81 public ModelDiffCursor getDiffCursor(long to) {
76 Model toModel = store.createModel(to); 82 Model toModel = store.createModel(to);
77 Map<DataRepresentation<?, ?>, DiffCursor<?, ?>> diffCursors = new HashMap<>(); 83 Map<AnyDataRepresentation, DiffCursor<?, ?>> diffCursors = new HashMap<>();
78 for (DataRepresentation<?, ?> representation : this.maps.keySet()) { 84 for (AnyDataRepresentation anyDataRepresentation : this.maps.keySet()) {
79 MapDiffCursor<?, ?> diffCursor = constructDiffCursor(toModel, representation); 85 var dataRepresentation = (DataRepresentation<?, ?>) anyDataRepresentation;
80 diffCursors.put(representation, diffCursor); 86 MapDiffCursor<?, ?> diffCursor = constructDiffCursor(toModel, dataRepresentation);
87 diffCursors.put(dataRepresentation, diffCursor);
81 } 88 }
82 return new ModelDiffCursor(diffCursors); 89 return new ModelDiffCursor(diffCursors);
83 } 90 }
@@ -113,12 +120,12 @@ public class ModelImpl implements Model {
113 120
114 @Override 121 @Override
115 public void restore(long state) { 122 public void restore(long state) {
116 if(store.getStates().contains(state)) { 123 if (store.getStates().contains(state)) {
117 for (VersionedMap<?, ?> map : maps.values()) { 124 for (VersionedMap<?, ?> map : maps.values()) {
118 map.restore(state); 125 map.restore(state);
119 } 126 }
120 } else { 127 } else {
121 throw new IllegalArgumentException("Map does not contain state "+state+"!"); 128 throw new IllegalArgumentException("Map does not contain state " + state + "!");
122 } 129 }
123 } 130 }
124} 131}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java b/subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java
index 9939f17e..79e4c9f9 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/internal/SimilarRelationEquivalenceClass.java
@@ -1,31 +1,33 @@
1package tools.refinery.store.model.internal; 1package tools.refinery.store.model.internal;
2 2
3import java.util.Objects;
4
5import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
6import tools.refinery.store.tuple.Tuple;
7import tools.refinery.store.model.representation.Relation; 4import tools.refinery.store.model.representation.Relation;
5import tools.refinery.store.tuple.Tuple;
6
7import java.util.Objects;
8 8
9public class SimilarRelationEquivalenceClass { 9public class SimilarRelationEquivalenceClass {
10 final ContinousHashProvider<Tuple> hashProvider; 10 final ContinousHashProvider<Tuple> hashProvider;
11 final Object defaultValue; 11 final Object defaultValue;
12 final int arity; 12 final int arity;
13
13 public SimilarRelationEquivalenceClass(Relation<?> representation) { 14 public SimilarRelationEquivalenceClass(Relation<?> representation) {
14 this.hashProvider = representation.getHashProvider(); 15 this.hashProvider = representation.getHashProvider();
15 this.defaultValue = representation.getDefaultValue(); 16 this.defaultValue = representation.getDefaultValue();
16 this.arity = representation.getArity(); 17 this.arity = representation.getArity();
17 } 18 }
19
18 @Override 20 @Override
19 public int hashCode() { 21 public int hashCode() {
20 return Objects.hash(arity, defaultValue, hashProvider); 22 return Objects.hash(arity, defaultValue, hashProvider);
21 } 23 }
24
22 @Override 25 @Override
23 public boolean equals(Object obj) { 26 public boolean equals(Object obj) {
24 if (this == obj) 27 if (this == obj)
25 return true; 28 return true;
26 if (!(obj instanceof SimilarRelationEquivalenceClass)) 29 if (!(obj instanceof SimilarRelationEquivalenceClass other))
27 return false; 30 return false;
28 SimilarRelationEquivalenceClass other = (SimilarRelationEquivalenceClass) obj;
29 return arity == other.arity && Objects.equals(defaultValue, other.defaultValue) 31 return arity == other.arity && Objects.equals(defaultValue, other.defaultValue)
30 && Objects.equals(hashProvider, other.hashProvider); 32 && Objects.equals(hashProvider, other.hashProvider);
31 } 33 }
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyAuxiliaryData.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyAuxiliaryData.java
new file mode 100644
index 00000000..951952e5
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyAuxiliaryData.java
@@ -0,0 +1,4 @@
1package tools.refinery.store.model.representation;
2
3public sealed interface AnyAuxiliaryData extends AnyDataRepresentation permits AuxiliaryData {
4}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyDataRepresentation.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyDataRepresentation.java
new file mode 100644
index 00000000..ea74a625
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyDataRepresentation.java
@@ -0,0 +1,9 @@
1package tools.refinery.store.model.representation;
2
3public sealed interface AnyDataRepresentation permits DataRepresentation, AnyRelation, AnyAuxiliaryData {
4 String getName();
5
6 Class<?> getKeyType();
7
8 Class<?> getValueType();
9}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyRelation.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyRelation.java
new file mode 100644
index 00000000..1d698c28
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AnyRelation.java
@@ -0,0 +1,9 @@
1package tools.refinery.store.model.representation;
2
3import tools.refinery.store.model.RelationLike;
4import tools.refinery.store.tuple.Tuple;
5
6public sealed interface AnyRelation extends AnyDataRepresentation, RelationLike permits Relation {
7 @Override
8 Class<Tuple> getKeyType();
9}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java
index 18c38151..dad1ccf4 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java
@@ -2,7 +2,7 @@ package tools.refinery.store.model.representation;
2 2
3import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
4 4
5public final class AuxiliaryData<K, V> extends DataRepresentation<K, V> { 5public final class AuxiliaryData<K, V> extends DataRepresentation<K, V> implements AnyAuxiliaryData {
6 private final ContinousHashProvider<K> hashProvider; 6 private final ContinousHashProvider<K> hashProvider;
7 7
8 public AuxiliaryData(String name, Class<K> keyType, ContinousHashProvider<K> hashProvider, Class<V> valueType, 8 public AuxiliaryData(String name, Class<K> keyType, ContinousHashProvider<K> hashProvider, Class<V> valueType,
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java
index 61c6291b..2bf498b9 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java
@@ -2,7 +2,7 @@ package tools.refinery.store.model.representation;
2 2
3import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
4 4
5public abstract sealed class DataRepresentation<K, V> permits Relation, AuxiliaryData { 5public abstract sealed class DataRepresentation<K, V> implements AnyDataRepresentation permits Relation, AuxiliaryData {
6 private final String name; 6 private final String name;
7 7
8 private final V defaultValue; 8 private final V defaultValue;
@@ -18,6 +18,7 @@ public abstract sealed class DataRepresentation<K, V> permits Relation, Auxiliar
18 this.valueType = valueType; 18 this.valueType = valueType;
19 } 19 }
20 20
21 @Override
21 public String getName() { 22 public String getName() {
22 return name; 23 return name;
23 } 24 }
@@ -30,10 +31,12 @@ public abstract sealed class DataRepresentation<K, V> permits Relation, Auxiliar
30 return defaultValue; 31 return defaultValue;
31 } 32 }
32 33
34 @Override
33 public Class<K> getKeyType() { 35 public Class<K> getKeyType() {
34 return keyType; 36 return keyType;
35 } 37 }
36 38
39 @Override
37 public Class<V> getValueType() { 40 public Class<V> getValueType() {
38 return valueType; 41 return valueType;
39 } 42 }
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java
index cc32257c..47a07536 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java
@@ -1,11 +1,10 @@
1package tools.refinery.store.model.representation; 1package tools.refinery.store.model.representation;
2 2
3import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
4import tools.refinery.store.model.RelationLike;
5import tools.refinery.store.model.TupleHashProvider; 4import tools.refinery.store.model.TupleHashProvider;
6import tools.refinery.store.tuple.Tuple; 5import tools.refinery.store.tuple.Tuple;
7 6
8public final class Relation<D> extends DataRepresentation<Tuple, D> implements RelationLike { 7public final class Relation<D> extends DataRepresentation<Tuple, D> implements AnyRelation {
9 private final int arity; 8 private final int arity;
10 9
11 public Relation(String name, int arity, Class<D> valueType, D defaultValue) { 10 public Relation(String name, int arity, Class<D> valueType, D defaultValue) {
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
index 41f47e64..3a69f3a4 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
@@ -1,17 +1,15 @@
1package tools.refinery.store.query; 1package tools.refinery.store.query;
2 2
3import tools.refinery.store.model.ModelStore; 3import tools.refinery.store.model.ModelStore;
4import tools.refinery.store.model.representation.DataRepresentation; 4import tools.refinery.store.model.representation.AnyDataRepresentation;
5import tools.refinery.store.query.view.RelationView; 5import tools.refinery.store.query.view.AnyRelationView;
6 6
7import java.util.Set; 7import java.util.Set;
8 8
9public interface QueryableModelStore extends ModelStore { 9public interface QueryableModelStore extends ModelStore {
10 @SuppressWarnings("squid:S1452") 10 Set<AnyDataRepresentation> getDataRepresentations();
11 Set<DataRepresentation<?, ?>> getDataRepresentations();
12 11
13 @SuppressWarnings("squid:S1452") 12 Set<AnyRelationView> getViews();
14 Set<RelationView<?>> getViews();
15 13
16 Set<DNF> getPredicates(); 14 Set<DNF> getPredicates();
17 15
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java
index bc107b76..e389f563 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java
@@ -7,6 +7,14 @@ public enum Modality {
7 MAY, 7 MAY,
8 CURRENT; 8 CURRENT;
9 9
10 public Modality negate() {
11 return switch(this) {
12 case MUST -> MAY;
13 case MAY -> MUST;
14 case CURRENT -> CURRENT;
15 };
16 }
17
10 @Override 18 @Override
11 public String toString() { 19 public String toString() {
12 return name().toLowerCase(Locale.ROOT); 20 return name().toLowerCase(Locale.ROOT);
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationViewAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationViewAtom.java
index 762a41f1..cf836541 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationViewAtom.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationViewAtom.java
@@ -1,17 +1,17 @@
1package tools.refinery.store.query.atom; 1package tools.refinery.store.query.atom;
2 2
3import tools.refinery.store.query.Variable; 3import tools.refinery.store.query.Variable;
4import tools.refinery.store.query.view.RelationView; 4import tools.refinery.store.query.view.AnyRelationView;
5 5
6import java.util.List; 6import java.util.List;
7import java.util.Objects; 7import java.util.Objects;
8 8
9public final class RelationViewAtom extends AbstractSubstitutionAtom<RelationView<?>> { 9public final class RelationViewAtom extends AbstractSubstitutionAtom<AnyRelationView> {
10 public RelationViewAtom(RelationView<?> target, List<Variable> substitution) { 10 public RelationViewAtom(AnyRelationView target, List<Variable> substitution) {
11 super(target, substitution); 11 super(target, substitution);
12 } 12 }
13 13
14 public RelationViewAtom(RelationView<?> target, Variable... substitution) { 14 public RelationViewAtom(AnyRelationView target, Variable... substitution) {
15 this(target, List.of(substitution)); 15 this(target, List.of(substitution));
16 } 16 }
17 17
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/AnyRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/AnyRelationView.java
new file mode 100644
index 00000000..df5e0d72
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/AnyRelationView.java
@@ -0,0 +1,13 @@
1package tools.refinery.store.query.view;
2
3import tools.refinery.store.model.Model;
4import tools.refinery.store.model.RelationLike;
5import tools.refinery.store.model.representation.AnyRelation;
6
7public sealed interface AnyRelationView extends RelationLike permits RelationView {
8 AnyRelation getRepresentation();
9
10 boolean get(Model model, Object[] tuple);
11
12 Iterable<Object[]> getAll(Model model);
13}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java
index 3b639979..5b892cc6 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java
@@ -3,6 +3,7 @@ package tools.refinery.store.query.view;
3import tools.refinery.store.tuple.Tuple; 3import tools.refinery.store.tuple.Tuple;
4import tools.refinery.store.model.representation.Relation; 4import tools.refinery.store.model.representation.Relation;
5 5
6import java.util.Objects;
6import java.util.function.BiPredicate; 7import java.util.function.BiPredicate;
7import java.util.function.Predicate; 8import java.util.function.Predicate;
8 9
@@ -31,4 +32,18 @@ public class FilteredRelationView<D> extends AbstractFilteredRelationView<D> {
31 public boolean filter(Tuple key, D value) { 32 public boolean filter(Tuple key, D value) {
32 return this.predicate.test(key, value); 33 return this.predicate.test(key, value);
33 } 34 }
35
36 @Override
37 public boolean equals(Object o) {
38 if (this == o) return true;
39 if (o == null || getClass() != o.getClass()) return false;
40 if (!super.equals(o)) return false;
41 FilteredRelationView<?> that = (FilteredRelationView<?>) o;
42 return Objects.equals(predicate, that.predicate);
43 }
44
45 @Override
46 public int hashCode() {
47 return Objects.hash(super.hashCode(), predicate);
48 }
34} 49}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java
index c88af5a4..f7e7d28a 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java
@@ -3,6 +3,8 @@ package tools.refinery.store.query.view;
3import tools.refinery.store.tuple.Tuple; 3import tools.refinery.store.tuple.Tuple;
4import tools.refinery.store.model.representation.Relation; 4import tools.refinery.store.model.representation.Relation;
5 5
6import java.util.Objects;
7
6public class KeyOnlyRelationView extends AbstractFilteredRelationView<Boolean> { 8public class KeyOnlyRelationView extends AbstractFilteredRelationView<Boolean> {
7 public static final String VIEW_NAME = "key"; 9 public static final String VIEW_NAME = "key";
8 10
@@ -17,4 +19,18 @@ public class KeyOnlyRelationView extends AbstractFilteredRelationView<Boolean> {
17 public boolean filter(Tuple key, Boolean value) { 19 public boolean filter(Tuple key, Boolean value) {
18 return !value.equals(defaultValue); 20 return !value.equals(defaultValue);
19 } 21 }
22
23 @Override
24 public boolean equals(Object o) {
25 if (this == o) return true;
26 if (o == null || getClass() != o.getClass()) return false;
27 if (!super.equals(o)) return false;
28 KeyOnlyRelationView that = (KeyOnlyRelationView) o;
29 return Objects.equals(defaultValue, that.defaultValue);
30 }
31
32 @Override
33 public int hashCode() {
34 return Objects.hash(super.hashCode(), defaultValue);
35 }
20} 36}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java
index 96f8584a..1224076c 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java
@@ -2,9 +2,8 @@ package tools.refinery.store.query.view;
2 2
3import tools.refinery.store.map.CursorAsIterator; 3import tools.refinery.store.map.CursorAsIterator;
4import tools.refinery.store.model.Model; 4import tools.refinery.store.model.Model;
5import tools.refinery.store.model.RelationLike;
6import tools.refinery.store.tuple.Tuple;
7import tools.refinery.store.model.representation.Relation; 5import tools.refinery.store.model.representation.Relation;
6import tools.refinery.store.tuple.Tuple;
8 7
9import java.util.Objects; 8import java.util.Objects;
10import java.util.UUID; 9import java.util.UUID;
@@ -15,7 +14,7 @@ import java.util.UUID;
15 * @param <D> 14 * @param <D>
16 * @author Oszkar Semerath 15 * @author Oszkar Semerath
17 */ 16 */
18public abstract class RelationView<D> implements RelationLike { 17public abstract non-sealed class RelationView<D> implements AnyRelationView {
19 private final Relation<D> representation; 18 private final Relation<D> representation;
20 19
21 private final String name; 20 private final String name;
@@ -29,6 +28,7 @@ public abstract class RelationView<D> implements RelationLike {
29 this(representation, UUID.randomUUID().toString()); 28 this(representation, UUID.randomUUID().toString());
30 } 29 }
31 30
31 @Override
32 public Relation<D> getRepresentation() { 32 public Relation<D> getRepresentation() {
33 return representation; 33 return representation;
34 } 34 }
@@ -42,28 +42,21 @@ public abstract class RelationView<D> implements RelationLike {
42 42
43 public abstract Object[] forwardMap(Tuple key, D value); 43 public abstract Object[] forwardMap(Tuple key, D value);
44 44
45 public abstract boolean get(Model model, Object[] tuple); 45 @Override
46
47 public Iterable<Object[]> getAll(Model model) { 46 public Iterable<Object[]> getAll(Model model) {
48 return (() -> new CursorAsIterator<>(model.getAll(representation), this::forwardMap, this::filter)); 47 return (() -> new CursorAsIterator<>(model.getAll(representation), this::forwardMap, this::filter));
49 } 48 }
50 49
51 @Override 50 @Override
52 public int hashCode() { 51 public boolean equals(Object o) {
53 final int prime = 31; 52 if (this == o) return true;
54 int result = 1; 53 if (o == null || getClass() != o.getClass()) return false;
55 result = prime * result + Objects.hash(representation); 54 RelationView<?> that = (RelationView<?>) o;
56 return result; 55 return Objects.equals(representation, that.representation) && Objects.equals(name, that.name);
57 } 56 }
58 57
59 @Override 58 @Override
60 public boolean equals(Object obj) { 59 public int hashCode() {
61 if (this == obj) 60 return Objects.hash(representation, name);
62 return true;
63 if (!(obj instanceof RelationView))
64 return false;
65 @SuppressWarnings("unchecked")
66 RelationView<D> other = ((RelationView<D>) obj);
67 return Objects.equals(representation, other.representation);
68 } 61 }
69} 62}