HCOLL-412 fix a bug in HashLookupSearch.putNewVolatile()

This commit is contained in:
leventov
2015-12-24 18:31:32 +03:00
parent b4688e012d
commit d060fd0c2d
3 changed files with 12 additions and 6 deletions
@@ -19,6 +19,7 @@ package net.openhft.chronicle.hash.impl.stage.entry;
import net.openhft.chronicle.hash.impl.CompactOffHeapLinearHashTable;
import net.openhft.chronicle.hash.impl.VanillaChronicleHashHolder;
import net.openhft.chronicle.hash.impl.stage.query.KeySearch;
import net.openhft.chronicle.map.impl.stage.entry.MapEntryStages;
import net.openhft.sg.Stage;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
@@ -32,6 +33,7 @@ public abstract class HashLookupSearch {
@StageRef public VanillaChronicleHashHolder<?> hh;
@StageRef HashLookupPos hlp;
@StageRef KeySearch<?> ks;
@StageRef MapEntryStages<?, ?> e;
@Stage("SearchKey") long searchKey = UNSET_KEY;
@Stage("SearchKey") public long searchStartPos;
@@ -78,17 +80,22 @@ public abstract class HashLookupSearch {
hlp.setHashLookupPos(hl().remove(addr(), hlp.hashLookupPos));
}
public void putNewVolatile(long value) {
public void putNewVolatile(long entryPos) {
// Correctness check + make putNewVolatile() dependant on keySearch, this, in turn,
// is needed for hlp.hashLookupPos re-initialization after nextTier().
// Not an assert statement, because ks.searchStatePresent() should run regardless assertions
// enabled or not.
boolean keySearchReInit = !ks.keySearchInit();
if (ks.searchStatePresent())
throw new AssertionError();
if (keySearchReInit) {
// if key search was re-init, entry was re-init too during the search
e.readExistingEntry(entryPos);
}
hl().checkValueForPut(value);
hl().checkValueForPut(entryPos);
long currentEntry = hl().readEntry(addr(), hlp.hashLookupPos);
hl().writeEntryVolatile(addr(), hlp.hashLookupPos, currentEntry, searchKey, value);
hl().writeEntryVolatile(addr(), hlp.hashLookupPos, currentEntry, searchKey, entryPos);
}
public boolean checkSlotContainsExpectedKeyAndValue(long value) {
@@ -51,7 +51,7 @@ public abstract class KeySearch<K> {
@Stage("KeySearch") protected SearchState searchState = null;
abstract boolean keySearchInit();
public abstract boolean keySearchInit();
@Stage("KeySearch")
public void setSearchState(SearchState newSearchState) {
@@ -22,11 +22,9 @@ import net.openhft.chronicle.hash.impl.stage.entry.SegmentStages;
import net.openhft.chronicle.hash.impl.stage.hash.CheckOnEachPublicOperation;
import net.openhft.chronicle.hash.impl.stage.query.HashQuery.EntryPresence;
import net.openhft.chronicle.hash.impl.stage.query.KeySearch;
import net.openhft.chronicle.map.MapAbsentEntry;
import net.openhft.chronicle.map.impl.VanillaChronicleMapHolder;
import net.openhft.chronicle.map.impl.stage.entry.MapEntryStages;
import net.openhft.chronicle.set.DummyValueData;
import net.openhft.chronicle.set.SetAbsentEntry;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
import org.jetbrains.annotations.NotNull;
@@ -89,6 +87,7 @@ public abstract class MapAbsent<K, V> implements Absent<K, V> {
public void doInsert() {
if (mh.set() == null)
throw new IllegalStateException("Called SetAbsentEntry.doInsert() from Map context");
//noinspection unchecked
doInsert((Data<V>) DummyValueData.INSTANCE);
}
}