Don't call MapEntryStages.readExistingEntry() until the key is found in initKeySearch() method

This commit is contained in:
leventov
2016-02-16 20:40:45 +07:00
parent a24c500bc7
commit 94af186ff5
3 changed files with 27 additions and 15 deletions
@@ -54,6 +54,10 @@ public abstract class HashEntryStages<K> implements HashEntry<K>, ChecksumEntry
public abstract boolean entryOffsetInit();
public void initEntryOffset(long keySizeOffset) {
this.keySizeOffset = keySizeOffset;
}
public void initEntryOffset() {
keySizeOffset = s.entrySpaceOffset + pos * hh.h().chunkSize;
}
@@ -80,6 +84,13 @@ public abstract class HashEntryStages<K> implements HashEntry<K>, ChecksumEntry
initKeyOffset(segmentBytes.readPosition());
}
public void readFoundEntry(long pos, long keySizeOffset, long keySize, long keyOffset) {
initPos(pos);
initEntryOffset(keySizeOffset);
initKeySize(keySize);
initKeyOffset(keyOffset);
}
public void writeNewEntry(long pos, Data<?> key) {
initPos(pos);
initKeySize(key.size());
@@ -603,7 +603,7 @@ public abstract class SegmentStages implements SegmentLock, LocksInterface {
@Stage("Segment") public final ReusableBitSet freeList = new ReusableBitSet(
new SingleThreadedFlatBitSetFrame(LONGS.align(hh.h().actualChunksPerSegmentTier, BITS)),
Access.nativeAccess(), null, 0);
@Stage("Segment") long entrySpaceOffset = 0;
@Stage("Segment") public long entrySpaceOffset = 0;
boolean segmentInit() {
return entrySpaceOffset > 0;
@@ -16,11 +16,13 @@
package net.openhft.chronicle.hash.impl.stage.query;
import net.openhft.chronicle.bytes.Bytes;
import net.openhft.chronicle.bytes.BytesUtil;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.impl.stage.entry.HashEntryStages;
import net.openhft.chronicle.hash.impl.stage.entry.HashLookupSearch;
import net.openhft.chronicle.hash.impl.stage.entry.SegmentStages;
import net.openhft.chronicle.map.impl.VanillaChronicleMapHolder;
import net.openhft.sg.Stage;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
@@ -31,6 +33,7 @@ import static net.openhft.chronicle.hash.impl.stage.query.KeySearch.SearchState.
@Staged
public abstract class KeySearch<K> {
@StageRef VanillaChronicleMapHolder<?, ?, ?> mh;
@StageRef public SegmentStages s;
@StageRef public HashLookupSearch hashLookupSearch;
@StageRef public HashEntryStages<K> entry;
@@ -65,30 +68,28 @@ public abstract class KeySearch<K> {
// the current segment, and insertion into the tiered segment requires to locate
// an empty slot in the hashLookup.
if (inputKeyInit()) {
entry.readExistingEntry(pos);
if (!keyEquals())
long keySizeOffset = s.entrySpaceOffset + pos * mh.m().chunkSize;
Bytes segmentBytes = s.segmentBytesForRead();
segmentBytes.readPosition(keySizeOffset);
long keySize = mh.h().keySizeMarshaller.readSize(segmentBytes);
long keyOffset = segmentBytes.readPosition();
if (!keyEquals(keySize, keyOffset))
continue;
hashLookupSearch.found();
keyFound();
entry.readFoundEntry(pos, keySizeOffset, keySize, keyOffset);
searchState = PRESENT;
return;
}
}
searchState = SearchState.ABSENT;
}
boolean keyEquals() {
return inputKey.size() == entry.keySize &&
BytesUtil.bytesEqual(s.segmentBS, entry.keyOffset,
inputKey.bytes(), inputKey.offset(), entry.keySize);
boolean keyEquals(long keySize, long keyOffset) {
return inputKey.size() == keySize &&
BytesUtil.bytesEqual(s.segmentBS, keyOffset,
inputKey.bytes(), inputKey.offset(), keySize);
}
@Stage("KeySearch")
void keyFound() {
searchState = PRESENT;
}
abstract void closeKeySearch();
public boolean searchStatePresent() {
return searchState == PRESENT;
}