Made listeners almost work for replication

This commit is contained in:
leventov
2015-06-02 19:02:55 +01:00
parent 62a50e2aee
commit f1da352a5d
45 changed files with 3472 additions and 3279 deletions
@@ -62,6 +62,8 @@ public interface ChronicleHash<K, C extends KeyContext<K>, EQC extends ExternalH
@NotNull
EQC queryContext(K key);
@NotNull EQC queryContext(Value<K, ?> key);
/**
* Checks the given predicate on each entry in this {@code ChronicleHash} until all entries
@@ -72,8 +72,8 @@ public interface Value<V, T> {
accessor.offset(source, index));
}
default <T2> void writeTo(WriteAccess<T2> access, T2 handle, long offset) {
Access.copy(access(), handle(), offset(), access, handle, offset, size());
default <T2> void writeTo(WriteAccess<T2> targetAccess, T2 target, long targetOffset) {
Access.copy(access(), handle(), offset(), targetAccess, target, targetOffset, size());
}
default <T2> void writeTo(StreamingDataOutput<?, ?, T2> output) {
@@ -83,8 +83,9 @@ public interface Value<V, T> {
}
default <S, T2, A extends WriteAccess<T2>> void writeTo(
Accessor<S, T2, A> accessor, S source, long index) {
writeTo(accessor.access(source), accessor.handle(source), accessor.offset(source, index));
Accessor<S, T2, A> targetAccessor, S target, long index) {
writeTo(targetAccessor.access(target), targetAccessor.handle(target),
targetAccessor.offset(target, index));
}
/**
@@ -28,7 +28,7 @@ import static net.openhft.chronicle.bytes.Access.nativeAccess;
public final class JavaLangBytesAccessors {
public static Accessor.Full<Bytes, ?> uncheckedBytesAccessor(Bytes bytes) {
return bytes instanceof NativeBytes ? NativeBytesAccessor.INSTANCE :
return bytes instanceof NativeBytes ? GenericBytesAccessor.INSTANCE :
GenericBytesAccessor.INSTANCE;
}
@@ -548,7 +548,7 @@ public final class ChannelProvider implements Closeable {
@Override
protected Closeable applyTo(ChronicleMapBuilder builder,
Replica map, EntryExternalizable entryExternalizable,
final ChronicleMap chronicleMap) {
final ReplicatedChronicleMap replicatedMap) {
add(chronicleChannel, map, entryExternalizable);
return this;
}
@@ -1473,7 +1473,8 @@ public final class ChronicleMapBuilder<K, V> implements
replicators.add(ch);
}
for (Replicator replicator : replicators) {
Closeable token = replicator.applyTo(this, result, result, map);
Closeable token = replicator.applyTo(this, result, result,
(ReplicatedChronicleMap)map);
if (replicators.size() == 1 && token.getClass() == UdpReplicator.class) {
LOG.warn(Replicators.ONLY_UDP_WARN_MESSAGE);
}
@@ -1,5 +1,6 @@
package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.Value;
import net.openhft.chronicle.hash.function.SerializableFunction;
import net.openhft.lang.Jvm;
import org.jetbrains.annotations.NotNull;
@@ -185,6 +186,12 @@ public class FilePerKeyChronicleMap implements ChronicleMap<String, String> {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public ExternalMapQueryContext<String, String, ?> queryContext(Value<String, ?> key) {
throw new UnsupportedOperationException();
}
@Override
public boolean forEachEntryWhile(Predicate<? super MapKeyContext<String, String>> predicate) {
throw new UnsupportedOperationException();
@@ -23,7 +23,10 @@ import org.jetbrains.annotations.NotNull;
/**
* SPI interface for customizing "low-level" modification operations on {@link ChronicleMap}
* entries.
* entries. All {@code ChronicleMap} modifications operate via and instance of this interface:
* <ul>
* <li>Ordinary query operations: {@code map.put()}, {@code map.compute()}. In fact, the</li>
* </ul>
*
* @param <K> the map key type
* @param <V> the map value type
@@ -172,33 +172,6 @@ public interface Replica extends Closeable {
}
/**
* provides a key and value from NativeBytes, this can be used in conjunction with the
* modification iterator to get the key and value out of the NativeBytes
*/
interface EntryResolver<K, V> {
/**
* gets the key from the entry
*
* @param entry the bytes which the bytes which point to the entry
* @param usingKey the key object to reuse, if possible
* @return the key which is in the entry
*/
K key(@NotNull Bytes entry, K usingKey);
/**
* gets the value from the entry
*
* @param entry the bytes which reference to the entry
* @param usingValue the value object to reuse, if possible
* @return the value which is in the entry or null if the value has been remove from the map
*/
V value(@NotNull Bytes entry, V usingValue);
boolean wasRemoved(@NotNull Bytes entry);
}
/**
* Implemented typically by a replicator, This interface provides the event, which will get
* called whenever a put() or remove() has occurred to the map
@@ -87,7 +87,7 @@ import static net.openhft.lang.collection.DirectBitSet.NOT_FOUND;
public class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
V, VI, MVI extends MetaBytesInterop<V, ? super VI>, R>
extends VanillaChronicleMap<K, KI, MKI, V, VI, MVI, R>
implements Replica, Replica.EntryExternalizable, Replica.EntryResolver<K, V> {
implements Replica, Replica.EntryExternalizable {
// for file, jdbc and UDP replication
public static final int RESERVED_MOD_ITER = 8;
public static final int ADDITIONAL_ENTRY_BYTES = 10;
@@ -108,6 +108,7 @@ public class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? sup
public transient MapRemoteOperations<K, V, R> remoteOperations =
DefaultSpi.mapRemoteOperations();
transient CompiledReplicatedMapQueryContext<K, KI, MKI, V, VI, MVI, R, ?> remoteOpContext;
transient CompiledReplicatedMapIterationContext<K, KI, MKI, V, VI, MVI, R, ?> remoteItContext;
public ReplicatedChronicleMap(@NotNull ChronicleMapBuilder<K, V> builder,
AbstractReplication replication)
@@ -291,10 +292,12 @@ public class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? sup
}
}
@Override
public boolean identifierCheck(@NotNull HashReplicableEntry<?> entry, int chronicleId) {
return entry.originIdentifier() == localIdentifier;
}
@Override
public int sizeOfEntry(@NotNull Bytes entry, int chronicleId) {
long start = entry.position();
@@ -413,12 +416,28 @@ public class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? sup
return q;
}
/**
* Assumed to be called from a single thread - the replication thread. Not to waste time
* for going into replication thread's threadLocal map, cache the context in Map's field
*/
private CompiledReplicatedMapQueryContext<K, KI, MKI, V, VI, MVI, R, ?> remoteOpContext() {
if (remoteOpContext == null) {
remoteOpContext = q().getContext();
remoteOpContext = q();
}
assert !remoteOpContext.usedInit();
remoteOpContext.initUsed(true);
return remoteOpContext;
}
private CompiledReplicatedMapIterationContext<K, KI, MKI, V, VI, MVI, R, ?> remoteItContext() {
if (remoteItContext == null) {
remoteItContext = i();
}
assert !remoteItContext.usedInit();
remoteItContext.initUsed(true);
return remoteItContext;
}
/**
* This method does not set a segment lock, A segment lock should be obtained before calling
* this method, especially when being used in a multi threaded context.
@@ -426,64 +445,9 @@ public class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? sup
@Override
public void readExternalEntry(@NotNull Bytes source) {
try (CompiledReplicatedMapQueryContext<K, KI, MKI, V, VI, MVI, R, ?> remoteOpContext =
remoteOpContext()) {
if (remoteOpContext.usedInit())
throw new IllegalStateException();
remoteOpContext.initUsed(true);
mapContext()) {
remoteOpContext.initReplicationInput(source);
}
}
@Override
public K key(@NotNull Bytes entry, K usingKey) {
final long start = entry.position();
try {
long keySize = keySizeMarshaller.readSize(entry);
ThreadLocalCopies copies = keyReaderProvider.getCopies(null);
return keyReaderProvider.get(copies, originalKeyReader).read(entry, keySize);
} finally {
entry.position(start);
}
}
@Override
public V value(@NotNull Bytes entry, V usingValue) {
final long start = entry.position();
try {
entry.skip(keySizeMarshaller.readSize(entry));
//timeStamp
entry.readLong();
final byte identifier = entry.readByte();
if (identifier != localIdentifier) {
return null;
}
final boolean isDeleted = entry.readBoolean();
long valueSize;
if (!isDeleted) {
valueSize = valueSizeMarshaller.readSize(entry);
assert valueSize > 0;
} else {
return null;
}
alignment.alignPositionAddr(entry);
ThreadLocalCopies copies = valueReaderProvider.getCopies(null);
BytesReader<V> valueReader = valueReaderProvider.get(copies, originalValueReader);
return valueReader.read(entry, valueSize, usingValue);
} finally {
entry.position(start);
}
}
@Override
public boolean wasRemoved(@NotNull Bytes entry) {
final long start = entry.position();
try {
return entry.readBoolean(keySizeMarshaller.readSize(entry) + 9L);
} finally {
entry.position(start);
remoteOpContext.processReplicatedEvent();
}
}
@@ -520,8 +484,6 @@ public class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? sup
private final ATSDirectBitSet changesForIteration;
private final int segmentIndexShift;
private final long posMask;
private final CompiledReplicatedMapQueryContext<K, KI, MKI, V, VI, MVI, ?, ?> context =
mapContext();
// records the current position of the cursor in the bitset
private volatile long position = -1L;
@@ -597,10 +559,10 @@ public class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? sup
this.position = position;
int segmentIndex = (int) (position >>> segmentIndexShift);
if (context.theSegmentIndexInit() && context.segmentIndex() != segmentIndex)
try (CompiledReplicatedMapIterationContext<K, KI, MKI, V, VI, MVI, R, ?> context =
iterationContext()) {
context.initTheSegmentIndex(segmentIndex);
context.updateLock().lock();
try {
context.updateLock().lock();
if (changesForUpdates.get(position)) {
entryCallback.onBeforeEntry();
@@ -609,7 +571,7 @@ public class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? sup
context.initEntry(segmentPos);
// if the entry should be ignored, we'll move the next entry
if (entryCallback.shouldBeIgnored(context.entry(), chronicleId)) {
if (entryCallback.shouldBeIgnored(context, chronicleId)) {
changesForUpdates.clear(position);
continue;
}
@@ -629,8 +591,6 @@ public class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? sup
// if the position was already cleared by another thread
// while we were trying to obtain segment lock (for example, in onRelocation()),
// go to pick up next (next iteration in while (true) loop)
} finally {
context.updateLock().unlock();
}
}
}
@@ -652,7 +612,7 @@ public class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? sup
re.originIdentifier() == localIdentifier)) {
raiseChange(segmentIndex, c.pos());
}
return false;
return true;
});
}
}
@@ -32,13 +32,14 @@ abstract class Replicator {
* associated with the replication. <p>This method isn't intended to be called from the client
* code.
*
* @param chronicleMap to wrap.
* @param builder the builder from which the map was constructed. The replicator may
* obtain some map configurations, not accessible via the map
* instance.
* @param map a replicated map instance. Provides basic tools for replication
* implementation.
* @param entryExternalizable the callback for ser/deser implementation in the replicator
* @param chronicleMap to wrap.
* @param replicatedMap
* @return a {@code Closeable} token to control replication resources. It should be closed on
* closing the replicated map.
* @throws java.io.IOException if an io error occurred during the replicator setup
@@ -49,5 +50,5 @@ abstract class Replicator {
*/
protected abstract Closeable applyTo(ChronicleMapBuilder builder,
Replica map, Replica.EntryExternalizable entryExternalizable,
final ChronicleMap chronicleMap) throws IOException;
final ReplicatedChronicleMap replicatedMap) throws IOException;
}
@@ -114,13 +114,13 @@ final class Replicators {
protected Closeable applyTo(@NotNull final ChronicleMapBuilder builder,
@NotNull final Replica replica,
@NotNull final Replica.EntryExternalizable entryExternalizable,
final ChronicleMap chronicleMap) throws IOException {
final ReplicatedChronicleMap replicatedMap) throws IOException {
TcpTransportAndNetworkConfig tcpConfig = replication.tcpTransportAndNetwork();
TcpReplicator.StatelessClientParameters statelessClientParameters =
new TcpReplicator.StatelessClientParameters(
(VanillaChronicleMap) chronicleMap,
replicatedMap,
builder.keyBuilder,
builder.valueBuilder);
@@ -139,7 +139,7 @@ final class Replicators {
protected Closeable applyTo(@NotNull final ChronicleMapBuilder builder,
@NotNull final Replica map,
@NotNull final Replica.EntryExternalizable entryExternalizable,
final ChronicleMap chronicleMap)
final ReplicatedChronicleMap replicatedMap)
throws IOException {
return new UdpReplicator(map, entryExternalizable, replicationConfig
);
@@ -20,6 +20,7 @@ package net.openhft.chronicle.map;
import net.openhft.chronicle.bytes.IORuntimeException;
import net.openhft.chronicle.core.util.CloseablesManager;
import net.openhft.chronicle.hash.Value;
import net.openhft.chronicle.hash.function.SerializableFunction;
import net.openhft.chronicle.hash.impl.util.BuildVersion;
import net.openhft.chronicle.hash.serialization.BytesReader;
@@ -552,6 +553,12 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
throw new UnsupportedOperationException("Contexts are not supported by stateless clients");
}
@NotNull
@Override
public ExternalMapQueryContext<K, V, ?> queryContext(Value<K, ?> key) {
throw new UnsupportedOperationException("Contexts are not supported by stateless clients");
}
public V get(Object key) {
return fetchObject(vClass, GET, (K) key);
}
@@ -24,8 +24,11 @@ import net.openhft.chronicle.hash.replication.RemoteNodeValidator;
import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig;
import net.openhft.chronicle.hash.replication.ThrottlingConfig;
import net.openhft.chronicle.hash.serialization.BytesReader;
import net.openhft.chronicle.hash.serialization.internal.MetaBytesInterop;
import net.openhft.chronicle.hash.serialization.internal.ReaderWithSize;
import net.openhft.chronicle.hash.serialization.internal.SerializationBuilder;
import net.openhft.chronicle.map.impl.CompiledReplicatedMapQueryContext;
import net.openhft.chronicle.map.impl.QueryContextInterface;
import net.openhft.lang.io.AbstractBytes;
import net.openhft.lang.io.ByteBufferBytes;
import net.openhft.lang.io.Bytes;
@@ -68,7 +71,7 @@ interface Work {
*
* @author Rob Austin.
*/
final class TcpReplicator<K, V> extends AbstractChannelReplicator implements Closeable {
public final class TcpReplicator<K, V> extends AbstractChannelReplicator implements Closeable {
public static final long TIMESTAMP_FACTOR = 10000;
private static final int STATELESS_CLIENT = -127;
@@ -106,7 +109,7 @@ final class TcpReplicator<K, V> extends AbstractChannelReplicator implements Clo
StatelessClientParameters<K, V> statelessClientParameters;
static class StatelessClientParameters<K, V> {
public StatelessClientParameters(VanillaChronicleMap<K, ?, ?, V, ?, ?, ?> map,
public StatelessClientParameters(ReplicatedChronicleMap<K, ?, ?, V, ?, ?, ?> map,
SerializationBuilder<K> keySerializationBuilder,
SerializationBuilder<V> valueSerializationBuilder) {
this.map = map;
@@ -114,7 +117,7 @@ final class TcpReplicator<K, V> extends AbstractChannelReplicator implements Clo
this.valueSerializationBuilder = valueSerializationBuilder;
}
VanillaChronicleMap<K, ?, ?, V, ?, ?, ?> map;
ReplicatedChronicleMap<K, ?, ?, V, ?, ?, ?> map;
SerializationBuilder<K> keySerializationBuilder;
SerializationBuilder<V> valueSerializationBuilder;
}
@@ -1052,7 +1055,7 @@ final class TcpReplicator<K, V> extends AbstractChannelReplicator implements Clo
/**
* @author Rob Austin.
*/
class TcpSocketChannelEntryWriter {
public class TcpSocketChannelEntryWriter {
@NotNull
@@ -1092,7 +1095,7 @@ final class TcpReplicator<K, V> extends AbstractChannelReplicator implements Clo
in().writeByte(localIdentifier);
}
void ensureBufferSize(long size) {
public void ensureBufferSize(long size) {
if (in().remaining() < size) {
size += entryCallback.in().position();
if (size > Integer.MAX_VALUE)
@@ -1118,7 +1121,7 @@ final class TcpReplicator<K, V> extends AbstractChannelReplicator implements Clo
throw e;
}
Bytes in() {
public Bytes in() {
return entryCallback.in();
}
@@ -1229,7 +1232,7 @@ final class TcpReplicator<K, V> extends AbstractChannelReplicator implements Clo
* localHeartbeatInterval
*/
private void writeHeartbeatToBuffer() {
// denotes the state - 0 for a beat
// denotes the state - 0 for a heartbeat
in().writeByte(HEARTBEAT.ordinal());
// denotes the size in bytes
@@ -1471,7 +1474,7 @@ final class TcpReplicator<K, V> extends AbstractChannelReplicator implements Clo
/**
* @author Rob Austin.
*/
class StatelessServerConnector<K, V> {
class StatelessServerConnector<K, V, R> {
private static final Logger LOG = LoggerFactory.getLogger(StatelessServerConnector.class
.getName());
@@ -1494,15 +1497,14 @@ class StatelessServerConnector<K, V> {
private final WriterWithSize<V> valueWriterWithSize;
@NotNull
private final VanillaChronicleMap<K, ?, ?, V, ?, ?, ?> map;
//private final BytesChronicleMap bytesMap;
private final ReplicatedChronicleMap<K, ?, ?, V, ?, ?, R> map;
private final SerializationBuilder<K> keySerializationBuilder;
private final SerializationBuilder<V> valueSerializationBuilder;
private final int tcpBufferSize;
StatelessServerConnector(
@NotNull VanillaChronicleMap<K, ?, ?, V, ?, ?, ?> map,
@NotNull ReplicatedChronicleMap<K, ?, ?, V, ?, ?, R> map,
@NotNull final BufferResizer bufferResizer, int tcpBufferSize,
final SerializationBuilder<K> keySerializationBuilder,
final SerializationBuilder<V> valueSerializationBuilder) {
@@ -1515,7 +1517,6 @@ class StatelessServerConnector<K, V> {
valueReaderWithSize = new ReaderWithSize<>(valueSerializationBuilder);
valueWriterWithSize = new WriterWithSize<>(valueSerializationBuilder, bufferResizer);
this.map = map;
//bytesMap = new BytesChronicleMap(map);
}
@Nullable
@@ -1699,13 +1700,22 @@ class StatelessServerConnector<K, V> {
return null;
}
private CompiledReplicatedMapQueryContext<K, ?, ?, V, ?, ?, R, ?> query(Bytes reader) {
CompiledReplicatedMapQueryContext<K, ?, ?, V, ?, ?, R, ?> q = map.mapContext();
q.initInputBytes(reader);
q.initInputKey(q.inputKeyBytesValue());
return q;
}
@Nullable
private Work removeWithValue(Bytes reader,
@NotNull TcpReplicator.TcpSocketChannelEntryWriter writer,
final long sizeLocation, long timestamp, byte id) {
try {
writer.ensureBufferSize(1L);
//writer.in().writeBoolean(bytesMap.remove(reader, reader));
try (CompiledReplicatedMapQueryContext<K, ?, ?, V, ?, ?, R, ?> q = query(reader)) {
writer.in().writeBoolean(map.methods.remove(q, q.inputFirstValueBytesValue()));
}
} catch (Throwable e) {
return sendException(writer, sizeLocation, e);
}
@@ -1719,7 +1729,10 @@ class StatelessServerConnector<K, V> {
final long sizeLocation, long timestamp, byte id) {
try {
writer.ensureBufferSize(1L);
//writer.in().writeBoolean(bytesMap.replace(reader, reader, reader));
try (CompiledReplicatedMapQueryContext<K, ?, ?, V, ?, ?, R, ?> q = query(reader)) {
writer.in().writeBoolean(map.methods.replace(q, q.inputFirstValueBytesValue(),
q.inputSecondValueBytesValue()));
}
} catch (Throwable e) {
return sendException(writer, sizeLocation, e);
}
@@ -1849,7 +1862,10 @@ class StatelessServerConnector<K, V> {
@NotNull TcpReplicator.TcpSocketChannelEntryWriter writer,
final long sizeLocation) {
try {
//writer.in().writeBoolean(bytesMap.containsKey(reader));
writer.ensureBufferSize(1L);
try (CompiledReplicatedMapQueryContext<K, ?, ?, V, ?, ?, R, ?> q = query(reader)) {
writer.in().writeBoolean(map.methods.containsKey(q));
}
} catch (Throwable e) {
return sendException(writer, sizeLocation, e);
}
@@ -1901,7 +1917,7 @@ class StatelessServerConnector<K, V> {
final long sizeLocation, long timestamp, byte id) {
//bytesMap.output = writer;
try {
// bytesMap.put(reader, reader);
//bytesMap.put(reader, reader);
} catch (Throwable e) {
return sendException(writer, sizeLocation, e);
} finally {
@@ -1914,20 +1930,20 @@ class StatelessServerConnector<K, V> {
@SuppressWarnings("SameReturnValue")
@Nullable
private Work remove(Bytes reader, long timestamp, byte id) {
//bytesMap.remove(reader);
// bytesMap.remove(reader);
return null;
}
@Nullable
private Work remove(Bytes reader, TcpReplicator.TcpSocketChannelEntryWriter writer,
final long sizeLocation, long timestamp, byte id) {
//bytesMap.output = writer;
// bytesMap.output = writer;
try {
// bytesMap.remove(reader);
// bytesMap.remove(reader);
} catch (Throwable e) {
return sendException(writer, sizeLocation, e);
} finally {
// bytesMap.output = null;
// bytesMap.output = null;
}
writeSizeAndFlags(sizeLocation, false, writer.in());
return null;
@@ -1939,7 +1955,7 @@ class StatelessServerConnector<K, V> {
final long sizeLocation,
long timestamp, byte id) {
try {
// bytesMap.putAll(reader);
// bytesMap.putAll(reader);
} catch (Throwable e) {
return sendException(writer, sizeLocation, e);
}
@@ -1950,7 +1966,7 @@ class StatelessServerConnector<K, V> {
@SuppressWarnings("SameReturnValue")
@Nullable
private Work putAll(@NotNull Bytes reader, long timestamp, byte id) {
//bytesMap.putAll(reader);
// bytesMap.putAll(reader);
return null;
}
@@ -2110,11 +2126,11 @@ class StatelessServerConnector<K, V> {
final long sizeLocation, long timestamp, byte id) {
// bytesMap.output = writer;
try {
// bytesMap.putIfAbsent(reader, reader);
// bytesMap.putIfAbsent(reader, reader);
} catch (Throwable e) {
return sendException(writer, sizeLocation, e);
} finally {
// bytesMap.output = null;
// bytesMap.output = null;
}
writeSizeAndFlags(sizeLocation, false, writer.in());
return null;
@@ -2123,13 +2139,13 @@ class StatelessServerConnector<K, V> {
@Nullable
private Work replace(Bytes reader, TcpReplicator.TcpSocketChannelEntryWriter writer,
final long sizeLocation, long timestamp, byte id) {
// bytesMap.output = writer;
// bytesMap.output = writer;
try {
// bytesMap.replace(reader, reader);
// bytesMap.replace(reader, reader);
} catch (Throwable e) {
return sendException(writer, sizeLocation, e);
} finally {
// bytesMap.output = null;
// bytesMap.output = null;
}
writeSizeAndFlags(sizeLocation, false, writer.in());
return null;
@@ -19,6 +19,7 @@
package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.KeyContext;
import net.openhft.chronicle.hash.Value;
import net.openhft.chronicle.hash.impl.VanillaChronicleHash;
import net.openhft.chronicle.hash.serialization.BytesReader;
import net.openhft.chronicle.hash.serialization.SizeMarshaller;
@@ -364,6 +365,14 @@ public class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super
return q;
}
@Override
@NotNull
public QueryContextInterface<K, V, R> queryContext(Value<K, ?> key) {
QueryContextInterface<K, V, R> q = mapContext();
q.initInputKey(key);
return q;
}
@Override
public V get(Object key) {
try (QueryContextInterface<K, V, R> q = queryContext(key)) {
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -19,6 +19,7 @@
package net.openhft.chronicle.set;
import net.openhft.chronicle.hash.KeyContext;
import net.openhft.chronicle.hash.Value;
import net.openhft.chronicle.hash.serialization.internal.DummyValue;
import net.openhft.chronicle.map.ChronicleMap;
import org.jetbrains.annotations.NotNull;
@@ -136,7 +137,14 @@ class SetFromMap<E> extends AbstractSet<E>
@Override
public ExternalSetQueryContext<E, ?> queryContext(E key) {
//TODO
return null;
throw new UnsupportedOperationException();
}
@NotNull
@Override
public ExternalSetQueryContext<E, ?> queryContext(Value<E, ?> key) {
//TODO
throw new UnsupportedOperationException();
}
@Override