diff options
author | OszkarSemerath <semerath@mit.bme.hu> | 2021-10-23 21:20:59 +0200 |
---|---|---|
committer | OszkarSemerath <semerath@mit.bme.hu> | 2021-10-23 21:20:59 +0200 |
commit | 5e6b39d330d7c23fd8f5903ea36d129e62997af8 (patch) | |
tree | 620ea4761935aeff0a12d0b31d386e7fe390aecb /store | |
parent | minor fixes (diff) | |
download | refinery-5e6b39d330d7c23fd8f5903ea36d129e62997af8.tar.gz refinery-5e6b39d330d7c23fd8f5903ea36d129e62997af8.tar.zst refinery-5e6b39d330d7c23fd8f5903ea36d129e62997af8.zip |
exotic map bug fix
Diffstat (limited to 'store')
-rw-r--r-- | store/src/main/java/tools/refinery/store/map/internal/MutableNode.java | 22 | ||||
-rw-r--r-- | store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java | 22 |
2 files changed, 32 insertions, 12 deletions
diff --git a/store/src/main/java/tools/refinery/store/map/internal/MutableNode.java b/store/src/main/java/tools/refinery/store/map/internal/MutableNode.java index 7e94758c..54853010 100644 --- a/store/src/main/java/tools/refinery/store/map/internal/MutableNode.java +++ b/store/src/main/java/tools/refinery/store/map/internal/MutableNode.java | |||
@@ -79,7 +79,7 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
79 | } | 79 | } |
80 | 80 | ||
81 | @Override | 81 | @Override |
82 | public Node<K, V> putValue(K key, V value, OldValueBox<V> oldValue, ContinousHashProvider<? super K> hashProvider, | 82 | public Node<K, V> putValue(K key, V value, OldValueBox<V> oldValueBox, ContinousHashProvider<? super K> hashProvider, |
83 | V defaultValue, int hash, int depth) { | 83 | V defaultValue, int hash, int depth) { |
84 | int selectedHashFragment = hashFragment(hash, shiftDepth(depth)); | 84 | int selectedHashFragment = hashFragment(hash, shiftDepth(depth)); |
85 | @SuppressWarnings("unchecked") | 85 | @SuppressWarnings("unchecked") |
@@ -89,20 +89,20 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
89 | if (keyCandidate.equals(key)) { | 89 | if (keyCandidate.equals(key)) { |
90 | // The key is equals to an existing key -> update entry | 90 | // The key is equals to an existing key -> update entry |
91 | if (value == defaultValue) { | 91 | if (value == defaultValue) { |
92 | return removeEntry(selectedHashFragment, oldValue); | 92 | return removeEntry(selectedHashFragment, oldValueBox); |
93 | } else { | 93 | } else { |
94 | return updateValue(value, oldValue, selectedHashFragment); | 94 | return updateValue(value, oldValueBox, selectedHashFragment); |
95 | } | 95 | } |
96 | } else { | 96 | } else { |
97 | // The key is not equivalent to an existing key on the same hash bin | 97 | // The key is not equivalent to an existing key on the same hash bin |
98 | // -> split entry if it is necessary | 98 | // -> split entry if it is necessary |
99 | if (value == defaultValue) { | 99 | if (value == defaultValue) { |
100 | // Value is default -> do not need to add new node | 100 | // Value is default -> do not need to add new node |
101 | oldValue.setOldValue(defaultValue); | 101 | oldValueBox.setOldValue(defaultValue); |
102 | return this; | 102 | return this; |
103 | } else { | 103 | } else { |
104 | // Value is not default -> Split entry data to a new node | 104 | // Value is not default -> Split entry data to a new node |
105 | oldValue.setOldValue(defaultValue); | 105 | oldValueBox.setOldValue(defaultValue); |
106 | return moveDownAndSplit(hashProvider, key, value, keyCandidate, hash, depth, selectedHashFragment); | 106 | return moveDownAndSplit(hashProvider, key, value, keyCandidate, hash, depth, selectedHashFragment); |
107 | } | 107 | } |
108 | } | 108 | } |
@@ -112,28 +112,26 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
112 | var nodeCandidate = (Node<K, V>) content[2 * selectedHashFragment + 1]; | 112 | var nodeCandidate = (Node<K, V>) content[2 * selectedHashFragment + 1]; |
113 | if (nodeCandidate != null) { | 113 | if (nodeCandidate != null) { |
114 | // If it has value, it is a subnode -> upate that | 114 | // If it has value, it is a subnode -> upate that |
115 | var newNode = nodeCandidate.putValue(key, value, oldValue, hashProvider, defaultValue, | 115 | var newNode = nodeCandidate.putValue(key, value, oldValueBox, hashProvider, defaultValue, |
116 | newHash(hashProvider, key, hash, depth + 1), depth + 1); | 116 | newHash(hashProvider, key, hash, depth + 1), depth + 1); |
117 | return updateWithSubNode(selectedHashFragment, newNode, value.equals(defaultValue)); | 117 | return updateWithSubNode(selectedHashFragment, newNode, value.equals(defaultValue)); |
118 | } else { | 118 | } else { |
119 | // If it does not have value, put it in the empty place | 119 | // If it does not have value, put it in the empty place |
120 | if (value == defaultValue) { | 120 | if (value == defaultValue) { |
121 | // dont need to add new key-value pair | 121 | // dont need to add new key-value pair |
122 | oldValue.setOldValue(defaultValue); | 122 | oldValueBox.setOldValue(defaultValue); |
123 | return this; | 123 | return this; |
124 | } else { | 124 | } else { |
125 | return addEntry(key, value, oldValue, selectedHashFragment); | 125 | return addEntry(key, value, oldValueBox, selectedHashFragment, defaultValue); |
126 | } | 126 | } |
127 | 127 | ||
128 | } | 128 | } |
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | private Node<K, V> addEntry(K key, V value, OldValueBox<V> oldValueBox, int selectedHashFragment) { | 132 | private Node<K, V> addEntry(K key, V value, OldValueBox<V> oldValueBox, int selectedHashFragment, V defaultValue) { |
133 | content[2 * selectedHashFragment] = key; | 133 | content[2 * selectedHashFragment] = key; |
134 | @SuppressWarnings("unchecked") | 134 | oldValueBox.setOldValue(defaultValue); |
135 | V oldValue = (V) content[2 * selectedHashFragment + 1]; | ||
136 | oldValueBox.setOldValue(oldValue); | ||
137 | content[2 * selectedHashFragment + 1] = value; | 135 | content[2 * selectedHashFragment + 1] = value; |
138 | updateHash(); | 136 | updateHash(); |
139 | return this; | 137 | return this; |
diff --git a/store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java b/store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java new file mode 100644 index 00000000..f0d5d927 --- /dev/null +++ b/store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java | |||
@@ -0,0 +1,22 @@ | |||
1 | package tools.refinery.store.map.tests; | ||
2 | |||
3 | import static org.junit.jupiter.api.Assertions.assertEquals; | ||
4 | |||
5 | import org.junit.jupiter.api.Test; | ||
6 | |||
7 | import tools.refinery.store.map.VersionedMapStore; | ||
8 | import tools.refinery.store.map.VersionedMapStoreImpl; | ||
9 | import tools.refinery.store.model.Tuple; | ||
10 | import tools.refinery.store.model.TupleHashProvider; | ||
11 | |||
12 | class MapUnitTests { | ||
13 | @Test | ||
14 | void defaultTest() { | ||
15 | VersionedMapStore<Tuple, Boolean> store = new VersionedMapStoreImpl<Tuple, Boolean>(TupleHashProvider.singleton(), false); | ||
16 | var map = store.createMap(); | ||
17 | var out1 = map.put(Tuple.of(0), true); | ||
18 | assertEquals(false, out1); | ||
19 | var out2 = map.put(Tuple.of(1), true); | ||
20 | assertEquals(false, out2); | ||
21 | } | ||
22 | } | ||