Moved DefaultValueProvider to the new Contexts API; removed defaultValue() SPI from MapEntryOperations (essentially replaced by DefaultValueProvider); Removed the old contexts, KeyContext and MapKeyContext completely

This commit is contained in:
leventov
2015-07-24 21:36:55 +03:00
parent 9fe1dab477
commit 340ab09409
23 changed files with 89 additions and 389 deletions
@@ -1,119 +0,0 @@
/*
* Copyright 2015 Higher Frequency Trading
*
* http://www.higherfrequencytrading.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.openhft.chronicle.hash;
import net.openhft.chronicle.hash.locks.InterProcessReadWriteUpdateLock;
import net.openhft.lang.io.Bytes;
import org.jetbrains.annotations.NotNull;
import java.util.ConcurrentModificationException;
/**
* Common considerations:
* <ul>
* <li>All method throw {@link ConcurrentModificationException} immediately, if called not from
* the thread, in which the context was obtained. {@code KeyContext} is strictly
* for single-thread access. For single try-with-resources block, actually, because:</li>
* <li>All methods throw {@code IllegalStateException} immediately, if called after
* {@link #close()} called on this context and returned.</li>
* </ul>
*
* @param <K> key type
* @deprecated incoherent abstraction. Replaced by {@link HashQueryContext} and {@link HashEntry}
*/
@Deprecated
public interface KeyContext<K> extends AutoCloseable, InterProcessReadWriteUpdateLock {
/**
* Returns the key object of this context. The instance might be reused, so you shouldn't
* save the returned object and use it after the context is closed or the callback (to which
* this context is provided) return. Might acquire {@link #readLock} before reading the key,
* if the context is not locked yet.
*
* @return the key object of this context
*/
@NotNull
K key();
/**
* Returns the entry bytes, if the key is present in the hash, otherwise throws
* {@code IllegalStateException}. Might acquire {@link #readLock} before searching for
* the entry, if the context is not locked yet.
*
* @return the entry bytes
* @throws IllegalStateException if the hash doesn't {@link #containsKey}
*/
@NotNull
Bytes entry();
/**
* Returns the offset of the key bytes within the {@link #entry}, if the key is present
* in the hash, otherwise throws {@code IllegalStateException}. Might acquire {@link #readLock}
* before searching for the entry, if the context is not locked yet.
*
* @return the offset of the key bytes within the {@link #entry}
* @throws IllegalStateException if the hash doesn't {@link #containsKey}
*/
long keyOffset();
/**
* Returns the size of the key bytes representation. Bytes from {@link #keyOffset} to
* {@code keyOffset + keySize} are the key bytes in the {@link #entry}.
*
* @return the size of the key bytes representation
*/
long keySize();
/**
* Checks if the key is present in the hash. Might acquire {@link #readLock} before searching
* for the key, if the context is not locked yet.
*
* @return {@code true} if the key is present in the hash, {@code false} otherwise
* @throws IllegalStateException if at least {@link #readLock} is not held
*/
boolean containsKey();
/**
* Removes the key from the hash. Might acquire {@link #updateLock} or {@link #writeLock},
* if the context is not locked yet. Might upgrade from update to write lock, if update lock
* is already held.
*
* @return {@code true} if the key was actually removed (hash was updated),
* {@code false} if the key is already absent in the hash
* @throws IllegalStateException if the context is locked for read, but not for update, and
* update or write lock is actually required for {@code remove()} in this {@code KeyContext}
* implementation
*/
boolean remove();
/**
* Closes the context. Among other things, it releases all locks, acquired within the context,
* that means you shouldn't bother with unlocking and try-finally pattern, if the whole
* context operation if performed within try-with-resources block: <pre>{@code
* try (KeyContext c = map.context(key)) {
* c.writeLock().lock();
* if (random.nextBoolean())
* c.remove();
* // Note, there is no c.writeLock().unlock(), and it's OK,
* // because all locks are released in close()
* }}</pre>
*/
@Override
void close();
}
@@ -18,7 +18,6 @@
package net.openhft.chronicle.map;
import net.openhft.chronicle.core.OS;
import net.openhft.chronicle.hash.ChronicleHashBuilder;
import net.openhft.chronicle.hash.ChronicleHashInstanceBuilder;
import net.openhft.chronicle.hash.impl.ChronicleHashBuilderImpl;
@@ -162,7 +161,8 @@ public final class ChronicleMapBuilder<K, V> implements
private BytesMarshallerFactory bytesMarshallerFactory;
private ObjectSerializer objectSerializer;
private V defaultValue = null;
private DefaultValueProvider<K, V> defaultValueProvider = null;
private ConstantValueProvider<V> constantValueProvider = null;
DefaultValueProvider<K, V> defaultValueProvider = DefaultSpi.defaultValueProvider();
private SingleChronicleHashReplication singleHashReplication = null;
private InetSocketAddress[] pushToAddresses;
@@ -943,7 +943,6 @@ public final class ChronicleMapBuilder<K, V> implements
", keyBuilder=" + keyBuilder +
", valueBuilder=" + valueBuilder +
", defaultValue=" + defaultValue +
", defaultValueProvider=" + pretty(defaultValueProvider) +
'}';
}
@@ -1144,7 +1143,7 @@ public final class ChronicleMapBuilder<K, V> implements
if (defaultValue == null)
throw new IllegalArgumentException("default ChronicleMap value couldn't be null");
this.defaultValue = defaultValue;
this.defaultValueProvider = null;
this.constantValueProvider = null;
return this;
}
@@ -1158,22 +1157,20 @@ public final class ChronicleMapBuilder<K, V> implements
* @param defaultValueProvider the strategy to obtain a default value by the absent key
* @return this builder object back
* @see #defaultValue(Object)
* @deprecated specialize {@link MapEntryOperations#defaultValue(MapAbsentEntry)} instead
*/
@Deprecated
public ChronicleMapBuilder<K, V> defaultValueProvider(
@NotNull DefaultValueProvider<K, V> defaultValueProvider) {
Objects.requireNonNull(defaultValueProvider);
this.defaultValueProvider = defaultValueProvider;
this.defaultValue = null;
return this;
}
/**
* Non-public because should be called only after {@link #preMapConstruction(boolean)}
*/
DefaultValueProvider<K, V> defaultValueProvider() {
if (defaultValueProvider != null)
return defaultValueProvider;
ConstantValueProvider<V> constantValueProvider() {
if (constantValueProvider != null)
return constantValueProvider;
V defaultValue = this.defaultValue;
if (defaultValue == null)
defaultValue = zeroValue();
@@ -1204,6 +1201,21 @@ public final class ChronicleMapBuilder<K, V> implements
try {
return DataValueClasses.newDirectInstance(valueBuilder.eClass);
} catch (Exception e) {
if (valueBuilder.eClass == Long.class) {
return (V) (Long) 0L;
} else if (valueBuilder.eClass == Integer.class) {
return (V) (Integer) 0;
} else if (valueBuilder.eClass == Short.class) {
return (V) (Short) (short) 0;
} else if (valueBuilder.eClass == Character.class) {
return (V) (Character) (char) 0;
} else if (valueBuilder.eClass == Byte.class) {
return (V) (Byte) (byte) 0;
} else if (valueBuilder.eClass == Float.class) {
return (V) (Float) 0.0f;
} else if (valueBuilder.eClass == Double.class) {
return (V) (Double) 0.0;
}
return null;
}
}
@@ -18,14 +18,17 @@
package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.KeyContext;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.serialization.BytesReader;
import net.openhft.chronicle.hash.serialization.internal.MetaBytesInterop;
import net.openhft.chronicle.hash.serialization.internal.MetaBytesWriter;
import net.openhft.chronicle.map.impl.stage.data.instance.WrappedValueInstanceData;
import net.openhft.lang.io.ByteBufferBytes;
import java.io.Serializable;
import java.nio.ByteBuffer;
final class ConstantValueProvider<K, V> implements DefaultValueProvider<K, V> {
public final class ConstantValueProvider<V> implements Serializable {
private static final long serialVersionUID = 0L;
private transient V value;
@@ -48,8 +51,7 @@ final class ConstantValueProvider<K, V> implements DefaultValueProvider<K, V> {
value = reader.read(new ByteBufferBytes(ByteBuffer.wrap(serializedValueBytes)), size);
}
@Override
public V get(KeyContext keyContext) {
public V defaultValue() {
return value;
}
}
@@ -2,7 +2,8 @@ package net.openhft.chronicle.map;
import net.openhft.chronicle.map.replication.MapRemoteOperations;
final class DefaultSpi implements MapMethods, MapEntryOperations, MapRemoteOperations {
final class DefaultSpi implements MapMethods, MapEntryOperations, MapRemoteOperations,
DefaultValueProvider {
static final DefaultSpi DEFAULT_SPI = new DefaultSpi();
static <K, V, R> MapMethods<K, V, R> mapMethods() {
return DEFAULT_SPI;
@@ -15,4 +16,8 @@ final class DefaultSpi implements MapMethods, MapEntryOperations, MapRemoteOpera
static <K, V, R> MapRemoteOperations<K, V, R> mapRemoteOperations() {
return DEFAULT_SPI;
}
static <K, V> DefaultValueProvider<K, V> defaultValueProvider() {
return DEFAULT_SPI;
}
}
@@ -18,9 +18,8 @@
package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.KeyContext;
import java.io.Serializable;
import net.openhft.chronicle.hash.Data;
import org.jetbrains.annotations.NotNull;
/**
* Default value computation strategy, used
@@ -28,16 +27,18 @@ import java.io.Serializable;
*
* @param <K> map key class
* @param <V> map value class
* @deprecated specialize {@link MapEntryOperations#defaultValue(MapAbsentEntry)} instead
* @see ChronicleMapBuilder#defaultValue(Object)
*/
@Deprecated
public interface DefaultValueProvider<K, V> extends Serializable {
public interface DefaultValueProvider<K, V> {
/**
* Returns a value to be put during {@link ChronicleMap#acquireUsing(Object, Object)} call
* for the specified key, if it is absent in the map.
* Returns the "nil" value, which should be inserted into the map, in the given
* {@code absentEntry} context. This is primarily used in {@link ChronicleMap#acquireUsing}
* operation implementation, i. e. {@link MapMethods#acquireUsing}.
*
* @param keyContext key absent in the map
* @return value to be put for the specified key in the map
* @implNote simply delegates to {@link MapAbsentEntry#defaultValue()}.
*/
V get(KeyContext keyContext);
default Data<V> defaultValue(@NotNull MapAbsentEntry<K, V> absentEntry) {
return absentEntry.defaultValue();
}
}
@@ -57,10 +57,10 @@ public interface MapAbsentEntry<K, V> extends HashAbsentEntry<K> {
* implementation, i. e. {@link MapMethods#acquireUsing}.
*
* <p>This method if the default implementation for {@link
* MapEntryOperations#defaultValue}, which might be customized over the default.
*
* @return the default value to be inserted into the map
* @see MapEntryOperations#defaultValue(MapAbsentEntry)
* DefaultValueProvider#defaultValue(MapAbsentEntry)},
* which might be customized over the default.
*
* @see DefaultValueProvider#defaultValue(MapAbsentEntry)
*/
@NotNull
Data<V> defaultValue();
@@ -31,7 +31,8 @@ import net.openhft.chronicle.hash.Data;
* @param <V> the map value type
* @param <R> the return type of {@link MapEntryOperations} specified for the queried map
*/
public interface MapContext<K, V, R> extends HashContext<K>, MapEntryOperations<K, V, R> {
public interface MapContext<K, V, R>
extends HashContext<K>, MapEntryOperations<K, V, R>, DefaultValueProvider<K, V> {
/**
* Returns the accessed {@code ChronicleMap}. Synonym to {@link #map()}.
*/
@@ -150,15 +150,4 @@ public interface MapEntryOperations<K, V, R> {
absentEntry.doInsert(value);
return null;
}
/**
* Returns the "nil" value, which should be inserted into the map, in the given
* {@code absentEntry} context. This is primarily used in {@link ChronicleMap#acquireUsing}
* operation implementation, i. e. {@link MapMethods#acquireUsing}.
*
* @implNote simply delegates to {@link MapAbsentEntry#defaultValue()}.
*/
default Data<V> defaultValue(@NotNull MapAbsentEntry<K, V> absentEntry) {
return absentEntry.defaultValue();
}
}
@@ -1,40 +0,0 @@
/*
* Copyright 2014 Higher Frequency Trading http://www.higherfrequencytrading.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.KeyContext;
/**
* @param <K> the map key type
* @param <V> the map value type
* @deprecated incoherent abstraction. Replaced by {@link MapQueryContext} and {@link MapEntry}
*/
@Deprecated
public interface MapKeyContext<K, V> extends KeyContext<K> {
long valueOffset();
long valueSize();
boolean valueEqualTo(V value);
V get();
V getUsing(V usingValue);
boolean put(V newValue);
}
@@ -20,7 +20,6 @@ package net.openhft.chronicle.map;
import net.openhft.chronicle.core.io.Closeable;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.KeyContext;
import net.openhft.chronicle.hash.impl.VanillaChronicleHash;
import net.openhft.chronicle.hash.serialization.BytesReader;
import net.openhft.chronicle.hash.serialization.SizeMarshaller;
@@ -67,7 +66,7 @@ public class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super
public final MVI originalMetaValueInterop;
public final MetaProvider<V, VI, MVI> metaValueInteropProvider;
final DefaultValueProvider<K, V> defaultValueProvider;
public final ConstantValueProvider<V> constantValueProvider;
public final boolean constantlySizedEntry;
@@ -91,9 +90,9 @@ public class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super
transient Set<Entry<K, V>> entrySet;
// TODO initialize
public transient MapEntryOperations<K, V, R> entryOperations;
public transient MapMethods<K, V, R> methods;
public transient DefaultValueProvider<K, V> defaultValueProvider;
transient ThreadLocal<?> queryCxt;
transient ThreadLocal<?> iterCxt;
@@ -123,7 +122,7 @@ public class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super
originalMetaValueInterop = (MVI) valueBuilder.metaInterop();
metaValueInteropProvider = (MetaProvider) valueBuilder.metaInteropProvider();
defaultValueProvider = builder.defaultValueProvider();
constantValueProvider = builder.constantValueProvider();
constantlySizedEntry = builder.constantlySizedEntries();
@@ -148,6 +147,7 @@ public class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super
void initTransientsFromBuilder(ChronicleMapBuilder<K, V> builder) {
this.entryOperations = (MapEntryOperations<K, V, R>) builder.entryOperations;
this.methods = (MapMethods<K, V, R>) builder.methods;
this.defaultValueProvider = builder.defaultValueProvider;
}
@Override
@@ -160,15 +160,12 @@ public class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super
valueReaderProvider = Provider.of((Class) originalValueReader.getClass());
valueInteropProvider = Provider.of((Class) originalValueInterop.getClass());
if (defaultValueProvider instanceof ConstantValueProvider) {
ConstantValueProvider<K, V> constantValueProvider =
(ConstantValueProvider<K, V>) defaultValueProvider;
if (constantValueProvider.wasDeserialized()) {
ThreadLocalCopies copies = valueReaderProvider.getCopies(null);
BytesReader<V> valueReader = valueReaderProvider.get(copies, originalValueReader);
constantValueProvider.initTransients(valueReader);
}
if (constantValueProvider != null && constantValueProvider.wasDeserialized()) {
ThreadLocalCopies copies = valueReaderProvider.getCopies(null);
BytesReader<V> valueReader = valueReaderProvider.get(copies, originalValueReader);
constantValueProvider.initTransients(valueReader);
}
initQueryContext();
initIterationContext();
}
@@ -209,14 +206,6 @@ public class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super
return actualSegments;
}
public V defaultValue(KeyContext keyContext) {
if (defaultValueProvider != null)
return defaultValueProvider.get(keyContext);
throw new IllegalStateException("To call acquire*() methods, " +
"you should specify either default value or default value provider " +
"during map building");
}
@Override
public V newValueInstance() {
if (vClass == CharSequence.class || vClass == StringBuilder.class)
@@ -95,7 +95,6 @@ nested = {
InputSecondValueBytesData.class,
WrappedValueInstanceData.class,
DeprecatedMapKeyContextOnQuery.class,
AcquireHandle.class,
DefaultReturnValue.class,
UsingReturnValue.class,
@@ -4,10 +4,9 @@ import net.openhft.chronicle.core.io.Closeable;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.impl.value.instance.KeyInitableData;
import net.openhft.chronicle.map.ExternalMapQueryContext;
import net.openhft.chronicle.map.MapKeyContext;
import net.openhft.chronicle.map.impl.data.instance.ValueInitializableData;
import net.openhft.chronicle.map.impl.ret.InstanceReturnValue;
import net.openhft.chronicle.map.impl.ret.UsableReturnValue;
import net.openhft.chronicle.map.impl.data.instance.ValueInitializableData;
public interface QueryContextInterface<K, V, R> extends ExternalMapQueryContext<K, V, R> {
@@ -21,8 +20,6 @@ public interface QueryContextInterface<K, V, R> extends ExternalMapQueryContext<
ValueInitializableData<V> inputValueInstanceValue();
MapKeyContext<K, V> deprecatedMapKeyContext();
Closeable acquireHandle();
void initTheSegmentIndex(int segmentIndex);
@@ -41,7 +41,10 @@ import net.openhft.chronicle.map.impl.stage.data.instance.WrappedValueInstanceDa
import net.openhft.chronicle.map.impl.stage.entry.ReplicatedMapEntryStages;
import net.openhft.chronicle.map.impl.stage.input.MapInputBytesValues;
import net.openhft.chronicle.map.impl.stage.input.ReplicatedInput;
import net.openhft.chronicle.map.impl.stage.map.*;
import net.openhft.chronicle.map.impl.stage.map.MapEntryOperationsDelegation;
import net.openhft.chronicle.map.impl.stage.map.ReplicatedChronicleMapHolderImpl;
import net.openhft.chronicle.map.impl.stage.map.ValueBytesInterop;
import net.openhft.chronicle.map.impl.stage.map.WrappedValueInstanceValueHolder;
import net.openhft.chronicle.map.impl.stage.query.*;
import net.openhft.chronicle.map.impl.stage.replication.ReplicationUpdate;
import net.openhft.chronicle.map.impl.stage.ret.BytesReturnValue;
@@ -100,7 +103,6 @@ nested = {
InputSecondValueBytesData.class,
WrappedValueInstanceData.class,
DeprecatedMapKeyContextOnQuery.class,
AcquireHandle.class,
DefaultReturnValue.class,
UsingReturnValue.class,
@@ -32,7 +32,7 @@ public abstract class MapEntryOperationsDelegation<K, V, R> implements MapContex
@Override
public Data<V> defaultValue(@NotNull MapAbsentEntry<K, V> absentEntry) {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return mh.m().entryOperations.defaultValue(absentEntry);
return mh.m().defaultValueProvider.defaultValue(absentEntry);
}
@Override
@@ -19,17 +19,11 @@
package net.openhft.chronicle.map.impl.stage.query;
import net.openhft.chronicle.core.io.Closeable;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.impl.stage.hash.CheckOnEachPublicOperation;
import net.openhft.chronicle.hash.locks.InterProcessLock;
import net.openhft.chronicle.map.MapEntry;
import net.openhft.chronicle.map.MapKeyContext;
import net.openhft.chronicle.map.impl.stage.entry.MapEntryStages;
import net.openhft.chronicle.map.impl.stage.ret.UsingReturnValue;
import net.openhft.lang.io.Bytes;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
import org.jetbrains.annotations.NotNull;
@Staged
public class AcquireHandle<K, V> implements Closeable {
@@ -1,148 +0,0 @@
/*
* Copyright 2015 Higher Frequency Trading
*
* http://www.higherfrequencytrading.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.openhft.chronicle.map.impl.stage.query;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.impl.stage.hash.CheckOnEachPublicOperation;
import net.openhft.chronicle.hash.locks.InterProcessLock;
import net.openhft.chronicle.map.MapEntry;
import net.openhft.chronicle.map.MapKeyContext;
import net.openhft.chronicle.map.impl.stage.entry.MapEntryStages;
import net.openhft.lang.io.Bytes;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
import org.jetbrains.annotations.NotNull;
@Staged
public class DeprecatedMapKeyContextOnQuery<K, V> implements MapKeyContext<K, V> {
@StageRef CheckOnEachPublicOperation checkOnEachPublicOperation;
@StageRef MapEntryStages<K, V> e;
@StageRef MapQuery<K, V, ?> q;
@Override
public long valueOffset() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return e.valueOffset;
}
@Override
public long valueSize() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return e.valueSize;
}
@Override
public boolean valueEqualTo(V value) {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return Data.bytesEquivalent(e.entryValue, q.wrapValueAsData(value));
}
@Override
public V get() {
return containsKey() ? q.value().get() : null;
}
@Override
public V getUsing(V usingValue) {
return containsKey() ? q.value().getUsing(usingValue) : null;
}
@Override
public boolean put(V newValue) {
checkOnEachPublicOperation.checkOnEachPublicOperation();
updateLock().lock();
MapEntry<K, V> entry = q.entry();
if (entry != null) {
q.replaceValue(entry, q.wrapValueAsData(newValue));
} else {
q.insert(q.absentEntry(), q.wrapValueAsData(newValue));
}
return true;
}
@NotNull
@Override
public K key() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return q.queriedKey().get();
}
@NotNull
@Override
public Bytes entry() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return e.entryBytes;
}
@Override
public long keyOffset() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return e.keyOffset;
}
@Override
public long keySize() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return e.keySize;
}
@Override
public boolean containsKey() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return q.entry() != null;
}
@Override
public boolean remove() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
updateLock().lock();
MapEntry<K, V> entry = q.entry();
if (entry != null) {
q.remove(entry);
return true;
} else {
return false;
}
}
@Override
public void close() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
q.close();
}
@NotNull
@Override
public InterProcessLock readLock() {
return q.readLock();
}
@NotNull
@Override
public InterProcessLock updateLock() {
return q.updateLock();
}
@NotNull
@Override
public InterProcessLock writeLock() {
return q.writeLock();
}
}
@@ -23,7 +23,6 @@ public class MapAbsent<K, V> implements MapAbsentEntry<K, V> {
@StageRef public CheckOnEachPublicOperation checkOnEachPublicOperation;
@StageRef public SegmentStages s;
@StageRef VanillaChronicleMapHolder<K, ?, ?, V, ?, ?, ?> mh;
@StageRef public DeprecatedMapKeyContextOnQuery<K, V> deprecatedMapKeyContext;
void putEntry(Data<V> value) {
assert q.searchStateAbsent();
@@ -69,6 +68,12 @@ public class MapAbsent<K, V> implements MapAbsentEntry<K, V> {
@Override
public Data<V> defaultValue() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return q.wrapValueAsData(mh.m().defaultValue(deprecatedMapKeyContext));
if (mh.m().constantValueProvider == null) {
throw new IllegalStateException("to call acquireUsing(), " +
"or defaultValue() on AbsentEntry, you should configure " +
"ChronicleMapBuilder.defaultValue(), or use one of the 'known' value types: " +
"boxed primitives, or so-called data-value-generated interface as a value");
}
return context().wrapValueAsData(mh.m().constantValueProvider.defaultValue());
}
}
@@ -49,7 +49,6 @@ public abstract class MapQuery<K, V, R> extends HashQuery<K>
@StageRef VanillaChronicleMapHolder<K, ?, ?, V, ?, ?, R> mh;
@StageRef MapEntryStages<K, V> e;
@StageRef SearchAllocatedChunks allocatedChunks;
@StageRef public DeprecatedMapKeyContextOnQuery<K, V> deprecatedMapKeyContext;
@StageRef public AcquireHandle<K, V> acquireHandle;
@StageRef public InputValueInstanceData<V, ?, ?> inputValueInstanceValue;
@@ -19,7 +19,6 @@
package net.openhft.chronicle.set;
import net.openhft.chronicle.hash.ChronicleHash;
import net.openhft.chronicle.hash.KeyContext;
import java.util.Set;
@@ -19,7 +19,6 @@
package net.openhft.chronicle.set;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.KeyContext;
import net.openhft.chronicle.hash.serialization.internal.DummyValue;
import net.openhft.chronicle.map.ChronicleMap;
import org.jetbrains.annotations.NotNull;