mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Remove REMOVED query state to reduce complexity
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user