Remove REMOVED query state to reduce complexity

This commit is contained in:
leventov
2016-02-16 20:40:47 +07:00
parent c3e436d390
commit 7293e5d7bb
6 changed files with 13 additions and 121 deletions
@@ -17,7 +17,6 @@
package net.openhft.chronicle.hash.impl.stage.query;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.HashEntry;
import net.openhft.chronicle.hash.impl.VanillaChronicleHashHolder;
import net.openhft.chronicle.hash.impl.stage.entry.HashEntryStages;
import net.openhft.chronicle.hash.impl.stage.entry.HashLookupPos;
@@ -30,7 +29,7 @@ import net.openhft.sg.Stage;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
import static net.openhft.chronicle.hash.impl.stage.query.KeySearch.SearchState.DELETED;
import static net.openhft.chronicle.hash.impl.stage.query.KeySearch.SearchState.ABSENT;
import static net.openhft.chronicle.hash.impl.stage.query.KeySearch.SearchState.PRESENT;
@Staged
@@ -137,7 +136,7 @@ public abstract class HashQuery<K> implements SetEntry<K> {
s.innerWriteLock.lock();
hashLookupSearch.remove();
entry.innerRemoveEntryExceptHashLookupUpdate();
ks.setSearchState(DELETED);
ks.setSearchState(ABSENT);
initPresenceOfEntry(EntryPresence.ABSENT);
} else {
throw new IllegalStateException("Entry is absent when doRemove() is called");
@@ -27,7 +27,7 @@ import net.openhft.sg.Stage;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
import static net.openhft.chronicle.hash.impl.stage.query.KeySearch.SearchState.DELETED;
import static net.openhft.chronicle.hash.impl.stage.query.KeySearch.SearchState.ABSENT;
import static net.openhft.chronicle.hash.impl.stage.query.KeySearch.SearchState.PRESENT;
@Staged
@@ -48,7 +48,6 @@ public abstract class KeySearch<K> {
public enum SearchState {
PRESENT,
DELETED,
ABSENT
}
@@ -94,12 +93,7 @@ public abstract class KeySearch<K> {
return searchState == PRESENT;
}
public boolean searchStateDeleted() {
return searchState == DELETED && !s.nestedContextsLockedOnSameSegment &&
s.innerUpdateLock.isHeldByCurrentThread();
}
public boolean searchStateAbsent() {
return !searchStatePresent() && !searchStateDeleted();
return searchState == ABSENT;
}
}
@@ -27,8 +27,12 @@ import net.openhft.chronicle.map.impl.stage.data.DummyValueZeroData;
import net.openhft.chronicle.map.impl.stage.data.bytes.EntryValueBytesData;
import net.openhft.chronicle.map.impl.stage.data.bytes.WrappedValueBytesData;
import net.openhft.chronicle.map.impl.stage.data.instance.WrappedValueInstanceDataHolder;
import net.openhft.chronicle.map.impl.stage.entry.MapEntryStages;
import net.openhft.chronicle.map.impl.stage.map.*;
import net.openhft.chronicle.map.impl.stage.query.*;
import net.openhft.chronicle.map.impl.stage.query.AcquireHandle;
import net.openhft.chronicle.map.impl.stage.query.MapAbsent;
import net.openhft.chronicle.map.impl.stage.query.MapQuery;
import net.openhft.chronicle.map.impl.stage.query.QueryCheckOnEachPublicOperation;
import net.openhft.chronicle.map.impl.stage.ret.DefaultReturnValue;
import net.openhft.chronicle.map.impl.stage.ret.UsingReturnValue;
import net.openhft.sg.Context;
@@ -53,7 +57,7 @@ import net.openhft.sg.Staged;
QueryCheckOnEachPublicOperation.class,
SearchAllocatedChunks.class,
QueryMapEntryStages.class,
MapEntryStages.class,
MapEntryOperationsDelegation.class,
WrappedValueInstanceDataHolderAccess.class,
WrappedValueBytesDataAccess.class,
@@ -49,6 +49,7 @@ public abstract class MapEntryStages<K, V> extends HashEntryStages<K>
public long valueSizeOffset = -1;
@SuppressWarnings("unused")
void initValueSizeOffset() {
valueSizeOffset = countValueSizeOffset();
}
@@ -69,6 +70,7 @@ public abstract class MapEntryStages<K, V> extends HashEntryStages<K>
valueOffset = segmentBytes.writePosition();
}
@SuppressWarnings("unused")
void initValueSize() {
Bytes segmentBytes = s.segmentBytesForRead();
segmentBytes.readPosition(valueSizeOffset);
@@ -76,11 +78,6 @@ public abstract class MapEntryStages<K, V> extends HashEntryStages<K>
valueOffset = segmentBytes.readPosition();
}
void initValueSize_EqualToOld(long oldValueSizeOffset, long oldValueSize, long oldValueOffset) {
valueSize = oldValueSize;
valueOffset = valueSizeOffset + (oldValueOffset - oldValueSizeOffset);
}
public void initValue(Data<?> value) {
initValueSize(value.size());
writeValue(value);
@@ -104,13 +101,6 @@ public abstract class MapEntryStages<K, V> extends HashEntryStages<K>
value.writeTo(s.segmentBS, valueOffset);
}
public void initValue_WithoutSize(
Data<?> value, long oldValueSizeOffset, long oldValueSize, long oldValueOffset) {
assert oldValueSize == value.size();
initValueSize_EqualToOld(oldValueSizeOffset, oldValueSize, oldValueOffset);
writeValue(value);
}
@Override
public long entryEnd() {
return valueOffset + valueSize;
@@ -125,17 +115,6 @@ public abstract class MapEntryStages<K, V> extends HashEntryStages<K>
return entryValue;
}
public void putValueDeletedEntry(Data<V> newValue) {
throw new AssertionError("putValueDeletedEntry() might be called only from " +
"non-Replicated Map query context");
}
public void writeValueAndPutPos(Data<V> value) {
initValue(value);
freeExtraAllocatedChunks();
hlp.putValueVolatile(pos);
}
public long newSizeOfEverythingBeforeValue(Data<V> newValue) {
return valueSizeOffset + mh.m().valueSizeMarshaller.storingLength(newValue.size()) -
keySizeOffset;
@@ -69,11 +69,7 @@ public abstract class MapAbsent<K, V> implements Absent<K, V> {
public void doInsert(Data<V> value) {
q.putPrefix();
if (!q.entryPresent()) {
if (ks.searchStateDeleted()) {
e.putValueDeletedEntry(value);
} else {
putEntry(value);
}
putEntry(value);
s.incrementModCount();
ks.setSearchState(PRESENT);
q.initPresenceOfEntry(EntryPresence.PRESENT);
@@ -1,80 +0,0 @@
/*
* Copyright (C) 2015 higherfrequencytrading.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.chronicle.map.impl.stage.query;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.impl.stage.entry.HashLookupSearch;
import net.openhft.chronicle.map.impl.stage.entry.MapEntryStages;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
import static net.openhft.chronicle.map.VanillaChronicleMap.alignAddr;
@Staged
public abstract class QueryMapEntryStages<K, V> extends MapEntryStages<K, V> {
@StageRef HashLookupSearch hls;
@Override
public void putValueDeletedEntry(Data<V> newValue) {
assert s.innerUpdateLock.isHeldByCurrentThread();
int newSizeInChunks;
long entryStartOffset = keySizeOffset;
long newSizeOfEverythingBeforeValue = -1;
boolean newValueSizeIsDifferent = newValue.size() != valueSize;
if (newValueSizeIsDifferent) {
newSizeOfEverythingBeforeValue = newSizeOfEverythingBeforeValue(newValue);
long newValueOffset =
alignAddr(entryStartOffset + newSizeOfEverythingBeforeValue, mh.m().alignment);
long newEntrySize = newEntrySize(newValue, entryStartOffset, newValueOffset);
newSizeInChunks = mh.m().inChunks(newEntrySize);
} else {
newSizeInChunks = entrySizeInChunks;
}
if (s.realloc(pos, 0, newSizeInChunks)) {
s.innerWriteLock.lock();
s.tierEntries(s.tierEntries() + 1);
if (newValueSizeIsDifferent) {
initValue(newValue);
} else {
writeValue(newValue);
}
} else {
if (newValueSizeIsDifferent) {
assert newSizeOfEverythingBeforeValue >= 0;
} else {
newSizeOfEverythingBeforeValue = newSizeOfEverythingBeforeValue(newValue);
}
long entrySize = innerEntrySize(newSizeOfEverythingBeforeValue, newValue.size());
if (newValueSizeIsDifferent) {
allocatedChunks.initEntryAndKeyCopying(
entrySize, valueSizeOffset - entryStartOffset, -1, 0);
initValue(newValue);
} else {
long oldValueSizeOffset = valueSizeOffset;
long oldValueSize = valueSize;
long oldValueOffset = valueOffset;
allocatedChunks.initEntryAndKeyCopying(
entrySize, valueOffset - entryStartOffset, -1, 0);
initValue_WithoutSize(newValue, oldValueSizeOffset, oldValueSize, oldValueOffset);
}
freeExtraAllocatedChunks();
}
hls.putNewVolatile(pos);
}
}