diff options
author | 2022-12-13 03:21:58 +0100 | |
---|---|---|
committer | 2022-12-13 12:25:02 +0100 | |
commit | 6ccc179ea305fc27ae121253b1d1f172bad676fd (patch) | |
tree | 8c5bb8dd7bf45157cabb57b19d17ce9af11aca5f /subprojects/store/src/main | |
parent | chore(deps): upgrade to yarn canary (diff) | |
download | refinery-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')
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 @@ | |||
1 | package tools.refinery.store.map; | ||
2 | |||
3 | public 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 @@ | |||
1 | package tools.refinery.store.map; | 1 | package tools.refinery.store.map; |
2 | 2 | ||
3 | import java.util.List; | 3 | import java.util.Set; |
4 | 4 | ||
5 | public interface Cursor<K,V> { | 5 | public 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 @@ | |||
1 | package tools.refinery.store.map; | 1 | package tools.refinery.store.map; |
2 | 2 | ||
3 | public interface VersionedMap<K,V> extends Versioned{ | 3 | public 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 @@ | |||
1 | package tools.refinery.store.map; | 1 | package tools.refinery.store.map; |
2 | 2 | ||
3 | public class VersionedMapStoreConfiguration { | 3 | public 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 @@ | |||
1 | package tools.refinery.store.map; | 1 | package tools.refinery.store.map; |
2 | 2 | ||
3 | import java.util.ArrayList; | ||
4 | import java.util.Arrays; | ||
5 | import java.util.Collections; | ||
6 | import java.util.HashMap; | ||
7 | import java.util.HashSet; | ||
8 | import java.util.List; | ||
9 | import java.util.Map; | ||
10 | import java.util.Set; | ||
11 | |||
12 | import tools.refinery.store.map.internal.ImmutableNode; | 3 | import tools.refinery.store.map.internal.ImmutableNode; |
13 | import tools.refinery.store.map.internal.MapDiffCursor; | 4 | import tools.refinery.store.map.internal.MapDiffCursor; |
14 | import tools.refinery.store.map.internal.Node; | 5 | import tools.refinery.store.map.internal.Node; |
15 | import tools.refinery.store.map.internal.VersionedMapImpl; | 6 | import tools.refinery.store.map.internal.VersionedMapImpl; |
16 | 7 | ||
8 | import java.util.*; | ||
9 | |||
17 | public class VersionedMapStoreImpl<K, V> implements VersionedMapStore<K, V> { | 10 | public 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 @@ | |||
1 | package tools.refinery.store.map.internal; | 1 | package tools.refinery.store.map.internal; |
2 | 2 | ||
3 | import tools.refinery.store.map.AnyVersionedMap; | ||
4 | import tools.refinery.store.map.Cursor; | ||
5 | import tools.refinery.store.map.VersionedMap; | ||
6 | |||
3 | import java.util.ArrayDeque; | 7 | import java.util.ArrayDeque; |
4 | import java.util.ConcurrentModificationException; | 8 | import java.util.ConcurrentModificationException; |
5 | import java.util.Iterator; | 9 | import java.util.Iterator; |
6 | import java.util.List; | 10 | import java.util.Set; |
7 | |||
8 | import tools.refinery.store.map.Cursor; | ||
9 | import tools.refinery.store.map.VersionedMap; | ||
10 | 11 | ||
11 | public class MapCursor<K,V> implements Cursor<K,V> { | 12 | public 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 @@ | |||
1 | package tools.refinery.store.map.internal; | 1 | package tools.refinery.store.map.internal; |
2 | 2 | ||
3 | import java.util.List; | 3 | import tools.refinery.store.map.AnyVersionedMap; |
4 | import java.util.stream.Stream; | ||
5 | |||
6 | import tools.refinery.store.map.ContinousHashProvider; | 4 | import tools.refinery.store.map.ContinousHashProvider; |
7 | import tools.refinery.store.map.Cursor; | 5 | import tools.refinery.store.map.Cursor; |
8 | import tools.refinery.store.map.DiffCursor; | 6 | import tools.refinery.store.map.DiffCursor; |
9 | import tools.refinery.store.map.VersionedMap; | 7 | |
8 | import java.util.Set; | ||
9 | import java.util.stream.Collectors; | ||
10 | import 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 @@ | |||
1 | package tools.refinery.store.map.internal; | 1 | package tools.refinery.store.map.internal; |
2 | 2 | ||
3 | import tools.refinery.store.map.*; | ||
4 | |||
3 | import java.util.Iterator; | 5 | import java.util.Iterator; |
4 | import java.util.LinkedList; | 6 | import java.util.LinkedList; |
5 | import java.util.List; | 7 | import java.util.List; |
6 | 8 | ||
7 | import tools.refinery.store.map.ContinousHashProvider; | ||
8 | import tools.refinery.store.map.Cursor; | ||
9 | import tools.refinery.store.map.DiffCursor; | ||
10 | import tools.refinery.store.map.VersionedMap; | ||
11 | import 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 | */ |
20 | public class VersionedMapImpl<K,V> implements VersionedMap<K,V>{ | 16 | public 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 @@ | |||
1 | package tools.refinery.store.model; | 1 | package tools.refinery.store.model; |
2 | 2 | ||
3 | import java.util.Set; | ||
4 | |||
5 | import tools.refinery.store.map.Cursor; | 3 | import tools.refinery.store.map.Cursor; |
6 | import tools.refinery.store.map.Versioned; | 4 | import tools.refinery.store.map.Versioned; |
5 | import tools.refinery.store.model.representation.AnyDataRepresentation; | ||
7 | import tools.refinery.store.model.representation.DataRepresentation; | 6 | import tools.refinery.store.model.representation.DataRepresentation; |
8 | 7 | ||
9 | public interface Model extends Versioned{ | 8 | import java.util.Set; |
10 | @SuppressWarnings("squid:S1452") | 9 | |
11 | Set<DataRepresentation<?, ?>> getDataRepresentations(); | 10 | public 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 @@ | |||
1 | package tools.refinery.store.model; | 1 | package tools.refinery.store.model; |
2 | 2 | ||
3 | import java.util.Map; | ||
4 | |||
5 | import tools.refinery.store.map.Cursor; | 3 | import tools.refinery.store.map.Cursor; |
6 | import tools.refinery.store.map.DiffCursor; | 4 | import tools.refinery.store.map.DiffCursor; |
5 | import tools.refinery.store.model.representation.AnyDataRepresentation; | ||
7 | import tools.refinery.store.model.representation.DataRepresentation; | 6 | import tools.refinery.store.model.representation.DataRepresentation; |
8 | 7 | ||
8 | import java.util.Map; | ||
9 | |||
9 | public class ModelDiffCursor { | 10 | public 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 @@ | |||
1 | package tools.refinery.store.model; | 1 | package tools.refinery.store.model; |
2 | 2 | ||
3 | import java.util.Set; | 3 | import tools.refinery.store.model.representation.AnyDataRepresentation; |
4 | 4 | ||
5 | import tools.refinery.store.model.representation.DataRepresentation; | 5 | import java.util.Set; |
6 | 6 | ||
7 | public interface ModelStore { | 7 | public 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; | |||
3 | import tools.refinery.store.map.*; | 3 | import tools.refinery.store.map.*; |
4 | import tools.refinery.store.model.internal.ModelImpl; | 4 | import tools.refinery.store.model.internal.ModelImpl; |
5 | import tools.refinery.store.model.internal.SimilarRelationEquivalenceClass; | 5 | import tools.refinery.store.model.internal.SimilarRelationEquivalenceClass; |
6 | import tools.refinery.store.model.representation.AnyDataRepresentation; | ||
6 | import tools.refinery.store.model.representation.AuxiliaryData; | 7 | import tools.refinery.store.model.representation.AuxiliaryData; |
7 | import tools.refinery.store.model.representation.DataRepresentation; | 8 | import tools.refinery.store.model.representation.DataRepresentation; |
8 | import tools.refinery.store.model.representation.Relation; | 9 | import tools.refinery.store.model.representation.Relation; |
@@ -13,26 +14,26 @@ import java.util.Map.Entry; | |||
13 | 14 | ||
14 | public class ModelStoreImpl implements ModelStore { | 15 | public 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 @@ | |||
1 | package tools.refinery.store.model.internal; | 1 | package tools.refinery.store.model.internal; |
2 | 2 | ||
3 | import java.util.HashMap; | ||
4 | import java.util.Map; | ||
5 | import java.util.Set; | ||
6 | |||
7 | import tools.refinery.store.map.ContinousHashProvider; | 3 | import tools.refinery.store.map.ContinousHashProvider; |
8 | import tools.refinery.store.map.Cursor; | 4 | import tools.refinery.store.map.Cursor; |
9 | import tools.refinery.store.map.DiffCursor; | 5 | import tools.refinery.store.map.DiffCursor; |
@@ -12,31 +8,41 @@ import tools.refinery.store.map.internal.MapDiffCursor; | |||
12 | import tools.refinery.store.model.Model; | 8 | import tools.refinery.store.model.Model; |
13 | import tools.refinery.store.model.ModelDiffCursor; | 9 | import tools.refinery.store.model.ModelDiffCursor; |
14 | import tools.refinery.store.model.ModelStore; | 10 | import tools.refinery.store.model.ModelStore; |
11 | import tools.refinery.store.model.representation.AnyDataRepresentation; | ||
15 | import tools.refinery.store.model.representation.DataRepresentation; | 12 | import tools.refinery.store.model.representation.DataRepresentation; |
16 | 13 | ||
14 | import java.util.HashMap; | ||
15 | import java.util.Map; | ||
16 | import java.util.Set; | ||
17 | |||
17 | public class ModelImpl implements Model { | 18 | public 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 @@ | |||
1 | package tools.refinery.store.model.internal; | 1 | package tools.refinery.store.model.internal; |
2 | 2 | ||
3 | import java.util.Objects; | ||
4 | |||
5 | import tools.refinery.store.map.ContinousHashProvider; | 3 | import tools.refinery.store.map.ContinousHashProvider; |
6 | import tools.refinery.store.tuple.Tuple; | ||
7 | import tools.refinery.store.model.representation.Relation; | 4 | import tools.refinery.store.model.representation.Relation; |
5 | import tools.refinery.store.tuple.Tuple; | ||
6 | |||
7 | import java.util.Objects; | ||
8 | 8 | ||
9 | public class SimilarRelationEquivalenceClass { | 9 | public 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 @@ | |||
1 | package tools.refinery.store.model.representation; | ||
2 | |||
3 | public 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 @@ | |||
1 | package tools.refinery.store.model.representation; | ||
2 | |||
3 | public 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 @@ | |||
1 | package tools.refinery.store.model.representation; | ||
2 | |||
3 | import tools.refinery.store.model.RelationLike; | ||
4 | import tools.refinery.store.tuple.Tuple; | ||
5 | |||
6 | public 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 | ||
3 | import tools.refinery.store.map.ContinousHashProvider; | 3 | import tools.refinery.store.map.ContinousHashProvider; |
4 | 4 | ||
5 | public final class AuxiliaryData<K, V> extends DataRepresentation<K, V> { | 5 | public 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 | ||
3 | import tools.refinery.store.map.ContinousHashProvider; | 3 | import tools.refinery.store.map.ContinousHashProvider; |
4 | 4 | ||
5 | public abstract sealed class DataRepresentation<K, V> permits Relation, AuxiliaryData { | 5 | public 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 @@ | |||
1 | package tools.refinery.store.model.representation; | 1 | package tools.refinery.store.model.representation; |
2 | 2 | ||
3 | import tools.refinery.store.map.ContinousHashProvider; | 3 | import tools.refinery.store.map.ContinousHashProvider; |
4 | import tools.refinery.store.model.RelationLike; | ||
5 | import tools.refinery.store.model.TupleHashProvider; | 4 | import tools.refinery.store.model.TupleHashProvider; |
6 | import tools.refinery.store.tuple.Tuple; | 5 | import tools.refinery.store.tuple.Tuple; |
7 | 6 | ||
8 | public final class Relation<D> extends DataRepresentation<Tuple, D> implements RelationLike { | 7 | public 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 @@ | |||
1 | package tools.refinery.store.query; | 1 | package tools.refinery.store.query; |
2 | 2 | ||
3 | import tools.refinery.store.model.ModelStore; | 3 | import tools.refinery.store.model.ModelStore; |
4 | import tools.refinery.store.model.representation.DataRepresentation; | 4 | import tools.refinery.store.model.representation.AnyDataRepresentation; |
5 | import tools.refinery.store.query.view.RelationView; | 5 | import tools.refinery.store.query.view.AnyRelationView; |
6 | 6 | ||
7 | import java.util.Set; | 7 | import java.util.Set; |
8 | 8 | ||
9 | public interface QueryableModelStore extends ModelStore { | 9 | public 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 @@ | |||
1 | package tools.refinery.store.query.atom; | 1 | package tools.refinery.store.query.atom; |
2 | 2 | ||
3 | import tools.refinery.store.query.Variable; | 3 | import tools.refinery.store.query.Variable; |
4 | import tools.refinery.store.query.view.RelationView; | 4 | import tools.refinery.store.query.view.AnyRelationView; |
5 | 5 | ||
6 | import java.util.List; | 6 | import java.util.List; |
7 | import java.util.Objects; | 7 | import java.util.Objects; |
8 | 8 | ||
9 | public final class RelationViewAtom extends AbstractSubstitutionAtom<RelationView<?>> { | 9 | public 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 @@ | |||
1 | package tools.refinery.store.query.view; | ||
2 | |||
3 | import tools.refinery.store.model.Model; | ||
4 | import tools.refinery.store.model.RelationLike; | ||
5 | import tools.refinery.store.model.representation.AnyRelation; | ||
6 | |||
7 | public 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; | |||
3 | import tools.refinery.store.tuple.Tuple; | 3 | import tools.refinery.store.tuple.Tuple; |
4 | import tools.refinery.store.model.representation.Relation; | 4 | import tools.refinery.store.model.representation.Relation; |
5 | 5 | ||
6 | import java.util.Objects; | ||
6 | import java.util.function.BiPredicate; | 7 | import java.util.function.BiPredicate; |
7 | import java.util.function.Predicate; | 8 | import 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; | |||
3 | import tools.refinery.store.tuple.Tuple; | 3 | import tools.refinery.store.tuple.Tuple; |
4 | import tools.refinery.store.model.representation.Relation; | 4 | import tools.refinery.store.model.representation.Relation; |
5 | 5 | ||
6 | import java.util.Objects; | ||
7 | |||
6 | public class KeyOnlyRelationView extends AbstractFilteredRelationView<Boolean> { | 8 | public 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 | ||
3 | import tools.refinery.store.map.CursorAsIterator; | 3 | import tools.refinery.store.map.CursorAsIterator; |
4 | import tools.refinery.store.model.Model; | 4 | import tools.refinery.store.model.Model; |
5 | import tools.refinery.store.model.RelationLike; | ||
6 | import tools.refinery.store.tuple.Tuple; | ||
7 | import tools.refinery.store.model.representation.Relation; | 5 | import tools.refinery.store.model.representation.Relation; |
6 | import tools.refinery.store.tuple.Tuple; | ||
8 | 7 | ||
9 | import java.util.Objects; | 8 | import java.util.Objects; |
10 | import java.util.UUID; | 9 | import 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 | */ |
18 | public abstract class RelationView<D> implements RelationLike { | 17 | public 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 | } |