From 5e6b39d330d7c23fd8f5903ea36d129e62997af8 Mon Sep 17 00:00:00 2001 From: OszkarSemerath Date: Sat, 23 Oct 2021 21:20:59 +0200 Subject: exotic map bug fix --- .../refinery/store/map/internal/MutableNode.java | 22 ++++++++++------------ .../refinery/store/map/tests/MapUnitTests.java | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java 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 extends Node { } @Override - public Node putValue(K key, V value, OldValueBox oldValue, ContinousHashProvider hashProvider, + public Node putValue(K key, V value, OldValueBox oldValueBox, ContinousHashProvider hashProvider, V defaultValue, int hash, int depth) { int selectedHashFragment = hashFragment(hash, shiftDepth(depth)); @SuppressWarnings("unchecked") @@ -89,20 +89,20 @@ public class MutableNode extends Node { if (keyCandidate.equals(key)) { // The key is equals to an existing key -> update entry if (value == defaultValue) { - return removeEntry(selectedHashFragment, oldValue); + return removeEntry(selectedHashFragment, oldValueBox); } else { - return updateValue(value, oldValue, selectedHashFragment); + return updateValue(value, oldValueBox, selectedHashFragment); } } else { // The key is not equivalent to an existing key on the same hash bin // -> split entry if it is necessary if (value == defaultValue) { // Value is default -> do not need to add new node - oldValue.setOldValue(defaultValue); + oldValueBox.setOldValue(defaultValue); return this; } else { // Value is not default -> Split entry data to a new node - oldValue.setOldValue(defaultValue); + oldValueBox.setOldValue(defaultValue); return moveDownAndSplit(hashProvider, key, value, keyCandidate, hash, depth, selectedHashFragment); } } @@ -112,28 +112,26 @@ public class MutableNode extends Node { var nodeCandidate = (Node) content[2 * selectedHashFragment + 1]; if (nodeCandidate != null) { // If it has value, it is a subnode -> upate that - var newNode = nodeCandidate.putValue(key, value, oldValue, hashProvider, defaultValue, + var newNode = nodeCandidate.putValue(key, value, oldValueBox, hashProvider, defaultValue, newHash(hashProvider, key, hash, depth + 1), depth + 1); return updateWithSubNode(selectedHashFragment, newNode, value.equals(defaultValue)); } else { // If it does not have value, put it in the empty place if (value == defaultValue) { // dont need to add new key-value pair - oldValue.setOldValue(defaultValue); + oldValueBox.setOldValue(defaultValue); return this; } else { - return addEntry(key, value, oldValue, selectedHashFragment); + return addEntry(key, value, oldValueBox, selectedHashFragment, defaultValue); } } } } - private Node addEntry(K key, V value, OldValueBox oldValueBox, int selectedHashFragment) { + private Node addEntry(K key, V value, OldValueBox oldValueBox, int selectedHashFragment, V defaultValue) { content[2 * selectedHashFragment] = key; - @SuppressWarnings("unchecked") - V oldValue = (V) content[2 * selectedHashFragment + 1]; - oldValueBox.setOldValue(oldValue); + oldValueBox.setOldValue(defaultValue); content[2 * selectedHashFragment + 1] = value; updateHash(); 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 @@ +package tools.refinery.store.map.tests; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +import tools.refinery.store.map.VersionedMapStore; +import tools.refinery.store.map.VersionedMapStoreImpl; +import tools.refinery.store.model.Tuple; +import tools.refinery.store.model.TupleHashProvider; + +class MapUnitTests { + @Test + void defaultTest() { + VersionedMapStore store = new VersionedMapStoreImpl(TupleHashProvider.singleton(), false); + var map = store.createMap(); + var out1 = map.put(Tuple.of(0), true); + assertEquals(false, out1); + var out2 = map.put(Tuple.of(1), true); + assertEquals(false, out2); + } +} -- cgit v1.2.3-70-g09d2