Removed ChronicleHash.context() method and changed acquireContext() return type from deprecated MapKeyContext to Closeable

This commit is contained in:
leventov
2015-07-24 03:43:50 +03:00
parent 5b23bd6f45
commit 912a3cc2fc
27 changed files with 689 additions and 667 deletions
@@ -48,12 +48,6 @@ public interface ChronicleHash<K, C extends KeyContext<K>, EQC extends ExternalH
long longSize();
/**
* @deprecated use {@link #queryContext} instead
*/
@Deprecated
C context(K key);
/**
* @return the class of {@code <K>}
*/
@@ -37,22 +37,24 @@ interface AbstractChronicleMap<K, V> extends ChronicleMap<K, V>, Serializable {
@Override
default <R> R getMapped(K key, @NotNull SerializableFunction<? super V, R> function) {
requireNonNull(function);
try (MapKeyContext<K, V> c = context(key)) {
return c.containsKey() ? function.apply(c.get()) : null;
try (ExternalMapQueryContext<K, V, ?> c = queryContext(key)) {
MapEntry<K, V> entry = c.entry();
return entry != null ? function.apply(entry.value().get()) : null;
}
}
@Override
default V putMapped(K key, @NotNull UnaryOperator<V> unaryOperator) {
requireNonNull(unaryOperator);
try (MapKeyContext<K, V> c = context(key)) {
try (ExternalMapQueryContext<K, V, ?> c = queryContext(key)) {
// putMapped() should find a value, update & put most of the time,
// so don't try to check key presence under read lock first,
// as in putIfAbsent()/acquireUsing(), start with update lock:
c.updateLock().lock();
if (c.containsKey()) {
V newValue = unaryOperator.update(c.get());
c.put(newValue);
MapEntry<K, V> entry = c.entry();
if (entry != null) {
V newValue = unaryOperator.update(entry.value().get());
c.replaceValue(entry, c.wrapValueAsData(newValue));
return newValue;
} else {
return null;
@@ -19,7 +19,6 @@
package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.ChronicleHash;
import net.openhft.chronicle.hash.ExternalHashQueryContext;
import net.openhft.chronicle.hash.function.SerializableFunction;
import net.openhft.chronicle.hash.serialization.BytesReader;
import net.openhft.lang.io.Bytes;
@@ -34,8 +33,6 @@ import java.io.Serializable;
import java.lang.Object;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* Extension of {@link ConcurrentMap} interface, stores the data off-heap.
@@ -142,13 +139,8 @@ public interface ChronicleMap<K, V>
*/
V acquireUsing(@NotNull K key, V usingValue);
/**
* @deprecated this method has incoherent, unclear semantics. Use {@link #queryContext(Object)}
* instead
*/
@Deprecated
@NotNull
MapKeyContext<K, V> acquireContext(@NotNull K key, @NotNull V usingValue);
net.openhft.chronicle.core.io.Closeable acquireContext(@NotNull K key, @NotNull V usingValue);
/**
* Apply a mapping to the value returned by a key and return a result. A read lock is assumed.
@@ -208,7 +200,7 @@ public interface ChronicleMap<K, V>
*
* {@link ChronicleMap#getUsing(Object, Object) }
* {@link ChronicleMap#acquireUsing(Object, Object) }
* {@link ChronicleMap#acquireContext(Object, Object) }
* {@link ChronicleMap#acquireContext(Object, Object)}
*
* for example like this :
*
@@ -232,8 +224,8 @@ public interface ChronicleMap<K, V>
* following methods :
*
* {@link ChronicleMap#getUsing(Object, Object) }
* {@link ChronicleMap#acquireUsing(Object, Object) }
* {@link ChronicleMap#acquireContext(Object, Object) }
* {@link ChronicleMap#acquireUsing(Object, Object)}
* {@link ChronicleMap#acquireContext(Object, Object)}
*
* for example like this :
*
@@ -70,12 +70,20 @@ class ReplicationHubFindByName<K> implements FindByName {
int withChannelId = nextFreeChannel.incrementAndGet();
try (MapKeyContext<CharSequence, MapInstanceBuilder> c = map.context(config.name)) {
try (ExternalMapQueryContext<CharSequence, MapInstanceBuilder, ?> c =
map.queryContext(config.name)) {
c.updateLock().lock();
MapInstanceBuilder value =
config.replicatedViaChannel(replicationHub.createChannel(withChannelId));
boolean added = !c.containsKey();
c.put(value);
boolean added;
MapEntry<CharSequence, MapInstanceBuilder> entry = c.entry();
if (entry != null) {
c.replaceValue(entry, c.wrapValueAsData(value));
added = false;
} else {
c.insert(c.absentEntry(), c.wrapValueAsData(value));
added = true;
}
if (added) {
// establish the new map based on this channel ID
@@ -542,11 +542,6 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
return fetchLong(LONG_SIZE);
}
@Override
public MapKeyContext<K, V> context(K key) {
throw new UnsupportedOperationException("Contexts are not supported by stateless clients");
}
@NotNull
@Override
public ExternalMapQueryContext<K, V, ?> queryContext(K key) {
@@ -598,7 +593,7 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
@NotNull
@Override
public MapKeyContext<K, V> acquireContext(@NotNull K key, @NotNull V usingValue) {
public net.openhft.chronicle.core.io.Closeable acquireContext(@NotNull K key, @NotNull V usingValue) {
throw new UnsupportedOperationException("Contexts are not supported by stateless clients");
}
@@ -18,6 +18,7 @@
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;
@@ -203,11 +204,6 @@ public class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super
return (V) value;
}
@Override
public MapKeyContext<K, V> context(K key) {
return queryContext(key).deprecatedMapKeyContext();
}
@Override
public int actualSegments() {
return actualSegments;
@@ -279,16 +275,15 @@ public class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super
}
}
@NotNull
@Override
public final MapKeyContext<K, V> acquireContext(K key, V usingValue) {
public final Closeable acquireContext(@NotNull K key, @NotNull V usingValue) {
QueryContextInterface<K, V, R> q = queryContext(key);
// TODO optimize to update lock in certain cases
try {
q.writeLock().lock();
acquireUsingBody(q, usingValue);
return q.deprecatedMapAcquireContext();
return q.acquireHandle();
} catch (Throwable e) {
try {
q.close();
@@ -298,7 +293,7 @@ public class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super
throw e;
}
}
private static <V> void checkAcquiredUsing(V acquired, V using) {
if (acquired != using) {
throw new IllegalArgumentException("acquire*() MUST reuse the given " +
@@ -348,7 +343,7 @@ public class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super
q.initUsed(true);
return q;
}
private CompiledMapIterationContext<K, KI, MKI, V, VI, MVI, R> i() {
return (CompiledMapIterationContext<K, KI, MKI, V, VI, MVI, R>) iterCxt.get();
}
@@ -30,9 +30,7 @@ class WriteThroughEntry<K, V> extends AbstractMap.SimpleEntry<K, V> {
@Override
public V setValue(V value) {
try (MapKeyContext<K, V> c = map.context(getKey())) {
c.put(value);
}
map.put(getKey(), value);
return super.setValue(value);
}
}
@@ -96,7 +96,7 @@ nested = {
WrappedValueInstanceData.class,
DeprecatedMapKeyContextOnQuery.class,
DeprecatedMapAcquireContextOnQuery.class,
AcquireHandle.class,
DefaultReturnValue.class,
UsingReturnValue.class,
})
@@ -1,12 +1,13 @@
package net.openhft.chronicle.map.impl;
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.ret.InstanceReturnValue;
import net.openhft.chronicle.map.impl.ret.UsableReturnValue;
import net.openhft.chronicle.map.impl.data.instance.ValueInitableData;
import net.openhft.chronicle.map.impl.data.instance.ValueInitializableData;
public interface QueryContextInterface<K, V, R> extends ExternalMapQueryContext<K, V, R> {
@@ -18,11 +19,11 @@ public interface QueryContextInterface<K, V, R> extends ExternalMapQueryContext<
UsableReturnValue<V> usingReturnValue();
ValueInitableData<V> inputValueInstanceValue();
ValueInitializableData<V> inputValueInstanceValue();
MapKeyContext<K, V> deprecatedMapKeyContext();
MapKeyContext<K, V> deprecatedMapAcquireContext();
Closeable acquireHandle();
void initTheSegmentIndex(int segmentIndex);
@@ -38,7 +38,6 @@ import net.openhft.chronicle.map.impl.stage.data.DummyValueZeroData;
import net.openhft.chronicle.map.impl.stage.data.bytes.*;
import net.openhft.chronicle.map.impl.stage.data.instance.InputValueInstanceData;
import net.openhft.chronicle.map.impl.stage.data.instance.WrappedValueInstanceData;
import net.openhft.chronicle.map.impl.stage.entry.MapEntryStages;
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;
@@ -102,7 +101,7 @@ nested = {
WrappedValueInstanceData.class,
DeprecatedMapKeyContextOnQuery.class,
DeprecatedMapAcquireContextOnQuery.class,
AcquireHandle.class,
DefaultReturnValue.class,
UsingReturnValue.class,
@@ -2,7 +2,7 @@ package net.openhft.chronicle.map.impl.data.instance;
import net.openhft.chronicle.hash.Data;
public interface ValueInitableData<V> extends Data<V> {
public interface ValueInitializableData<V> extends Data<V> {
void initValue(V value);
}
@@ -34,7 +34,6 @@ public class EntryValueBytesData<V> extends AbstractData<V> {
@StageRef MapEntryStages<?, V> entry;
@StageRef CheckOnEachPublicOperation checkOnEachPublicOperation;
@Stage("CachedEntryValue") private V cachedEntryValue;
@Stage("CachedEntryValue") private boolean cachedEntryValueRead = false;
@@ -20,7 +20,7 @@ package net.openhft.chronicle.map.impl.stage.data.instance;
import net.openhft.chronicle.hash.impl.CopyingInstanceData;
import net.openhft.chronicle.hash.serialization.internal.MetaBytesInterop;
import net.openhft.chronicle.map.impl.data.instance.ValueInitableData;
import net.openhft.chronicle.map.impl.data.instance.ValueInitializableData;
import net.openhft.chronicle.map.impl.stage.map.ValueBytesInterop;
import net.openhft.lang.io.DirectBytes;
import net.openhft.sg.Stage;
@@ -29,7 +29,7 @@ import net.openhft.sg.Staged;
@Staged
public abstract class InputValueInstanceData<V, VI, MVI extends MetaBytesInterop<V, ? super VI>>
extends CopyingInstanceData<V> implements ValueInitableData<V> {
extends CopyingInstanceData<V> implements ValueInitializableData<V> {
@StageRef ValueBytesInterop<V, VI, MVI> vi;
@@ -0,0 +1,48 @@
/*
* 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.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 {
@StageRef CheckOnEachPublicOperation checkOnEachPublicOperation;
@StageRef MapEntryStages<K, V> e;
@StageRef MapQuery<K, V, ?> q;
@StageRef UsingReturnValue<V> usingReturn;
@Override
public void close() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
q.replaceValue(q.entry(), q.wrapValueAsData(usingReturn.returnValue()));
q.close();
}
}
@@ -1,152 +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.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 DeprecatedMapAcquireContextOnQuery<K, V> implements MapKeyContext<K, V> {
@StageRef CheckOnEachPublicOperation checkOnEachPublicOperation;
@StageRef MapEntryStages<K, V> e;
@StageRef MapQuery<K, V, ?> q;
@StageRef UsingReturnValue<V> usingReturn;
@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() {
assert containsKey();
return usingReturn.returnValue();
}
@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();
put(usingReturn.returnValue());
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();
}
}
@@ -50,7 +50,7 @@ public abstract class MapQuery<K, V, R> extends HashQuery<K>
@StageRef MapEntryStages<K, V> e;
@StageRef SearchAllocatedChunks allocatedChunks;
@StageRef public DeprecatedMapKeyContextOnQuery<K, V> deprecatedMapKeyContext;
@StageRef public DeprecatedMapAcquireContextOnQuery<K, V> deprecatedMapAcquireContext;
@StageRef public AcquireHandle<K, V> acquireHandle;
@StageRef public InputValueInstanceData<V, ?, ?> inputValueInstanceValue;
@@ -123,11 +123,6 @@ class SetFromMap<E> extends AbstractSet<E>
return m.longSize();
}
@Override
public KeyContext context(E key) {
return m.context(key);
}
@Override
public Class<E> keyClass() {
return m.keyClass();