mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
HCOLL-412 fix a bug in HashLookupSearch.putNewVolatile()
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user