mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Added support for dynamic discovery of files, https://github.com/OpenHFT/Chronicle-Core/issues/88
This commit is contained in:
@@ -25,6 +25,7 @@ import net.openhft.chronicle.set.ChronicleSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
@@ -96,6 +97,11 @@ public interface ChronicleHash<K, E extends HashEntry<K>, SC extends HashSegment
|
||||
*/
|
||||
Class<K> keyClass();
|
||||
|
||||
/**
|
||||
* @return Type as a Class or UnresolvedType if unknown.
|
||||
*/
|
||||
Type keyType();
|
||||
|
||||
/**
|
||||
* Returns a context to perform arbitrary operations with the given key in this store.
|
||||
* Conventionally, should be used in a try-with-resources block: <pre>{@code
|
||||
|
||||
@@ -38,6 +38,7 @@ import net.openhft.chronicle.map.ChronicleMapBuilder;
|
||||
import net.openhft.chronicle.values.Values;
|
||||
import net.openhft.chronicle.wire.Marshallable;
|
||||
import net.openhft.chronicle.wire.WireIn;
|
||||
import net.openhft.chronicle.wire.WireInternal;
|
||||
import net.openhft.chronicle.wire.WireOut;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -46,6 +47,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
@@ -93,7 +95,7 @@ public abstract class VanillaChronicleHash<K,
|
||||
public transient boolean createdOrInMemory;
|
||||
/////////////////////////////////////////////////
|
||||
// Key Data model
|
||||
public Class<K> keyClass;
|
||||
public Type keyClass;
|
||||
public SizeMarshaller keySizeMarshaller;
|
||||
public SizedReader<K> keyReader;
|
||||
public DataAccess<K> keyDataAccess;
|
||||
@@ -247,7 +249,7 @@ public abstract class VanillaChronicleHash<K,
|
||||
// that doesn't guarantee (?) to initialize fields with default values (false for boolean)
|
||||
createdOrInMemory = false;
|
||||
|
||||
keyClass = wireIn.read(() -> "keyClass").typeLiteral();
|
||||
keyClass = wireIn.read(() -> "keyClass").lenientTypeLiteral();
|
||||
keySizeMarshaller = wireIn.read(() -> "keySizeMarshaller").object(SizeMarshaller.class);
|
||||
keyReader = wireIn.read(() -> "keyReader").object(SizedReader.class);
|
||||
keyDataAccess = wireIn.read(() -> "keyDataAccess").object(DataAccess.class);
|
||||
@@ -682,8 +684,10 @@ public abstract class VanillaChronicleHash<K,
|
||||
}
|
||||
|
||||
public final void checkKey(Object key) {
|
||||
Class<K> keyClass = keyClass();
|
||||
if (!keyClass.isInstance(key)) {
|
||||
// key.getClass will cause NPE exactly as needed
|
||||
if (key == null)
|
||||
throw new NullPointerException("null key not supported");
|
||||
throw new ClassCastException(toIdentityString() + ": Key must be a " +
|
||||
keyClass.getName() + " but was a " + key.getClass());
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import net.openhft.chronicle.hash.serialization.DataAccess;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class ByteableDataAccess<T extends Byteable> extends InstanceCreatingMarshaller<T>
|
||||
implements DataAccess<T>, Data<T> {
|
||||
|
||||
@@ -31,7 +33,7 @@ public class ByteableDataAccess<T extends Byteable> extends InstanceCreatingMars
|
||||
*/
|
||||
private transient T instance;
|
||||
|
||||
public ByteableDataAccess(Class<T> tClass) {
|
||||
public ByteableDataAccess(Type tClass) {
|
||||
super(tClass);
|
||||
}
|
||||
|
||||
@@ -91,6 +93,6 @@ public class ByteableDataAccess<T extends Byteable> extends InstanceCreatingMars
|
||||
|
||||
@Override
|
||||
public DataAccess<T> copy() {
|
||||
return new ByteableDataAccess<>(tClass());
|
||||
return new ByteableDataAccess<>(tType());
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -23,6 +23,8 @@ import net.openhft.chronicle.wire.WireIn;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import static net.openhft.chronicle.hash.serialization.impl.DefaultElasticBytes.DEFAULT_BYTES_CAPACITY;
|
||||
|
||||
public class BytesMarshallableDataAccess<T extends BytesMarshallable>
|
||||
@@ -42,7 +44,7 @@ public class BytesMarshallableDataAccess<T extends BytesMarshallable>
|
||||
this(tClass, DEFAULT_BYTES_CAPACITY);
|
||||
}
|
||||
|
||||
private BytesMarshallableDataAccess(Class<T> tClass, long bytesCapacity) {
|
||||
private BytesMarshallableDataAccess(Type tClass, long bytesCapacity) {
|
||||
super(tClass);
|
||||
initTransients(bytesCapacity);
|
||||
}
|
||||
@@ -140,6 +142,6 @@ public class BytesMarshallableDataAccess<T extends BytesMarshallable>
|
||||
|
||||
@Override
|
||||
public DataAccess<T> copy() {
|
||||
return new BytesMarshallableDataAccess<>(tClass(), bytes.realCapacity());
|
||||
return new BytesMarshallableDataAccess<>(tType(), bytes.realCapacity());
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -27,6 +27,8 @@ import net.openhft.chronicle.wire.WireOut;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import static net.openhft.chronicle.hash.serialization.StatefulCopyable.copyIfNeeded;
|
||||
import static net.openhft.chronicle.hash.serialization.impl.DefaultElasticBytes.DEFAULT_BYTES_CAPACITY;
|
||||
|
||||
@@ -53,7 +55,7 @@ public class ExternalBytesMarshallableDataAccess<T> extends InstanceCreatingMars
|
||||
}
|
||||
|
||||
private ExternalBytesMarshallableDataAccess(
|
||||
Class<T> tClass, SizedReader<T> reader, BytesWriter<? super T> writer,
|
||||
Type tClass, SizedReader<T> reader, BytesWriter<? super T> writer,
|
||||
long bytesCapacity) {
|
||||
super(tClass);
|
||||
this.writer = writer;
|
||||
@@ -125,7 +127,7 @@ public class ExternalBytesMarshallableDataAccess<T> extends InstanceCreatingMars
|
||||
@Override
|
||||
public DataAccess<T> copy() {
|
||||
return new ExternalBytesMarshallableDataAccess<>(
|
||||
tClass(), copyIfNeeded(reader), copyIfNeeded(writer), bytes.realCapacity());
|
||||
tType(), copyIfNeeded(reader), copyIfNeeded(writer), bytes.realCapacity());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+14
-4
@@ -26,6 +26,8 @@ import net.openhft.chronicle.wire.WireIn;
|
||||
import net.openhft.chronicle.wire.WireOut;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Holds new instance creation logic, common for many {@link DataAccess} and {@link SizedReader}
|
||||
* implementations
|
||||
@@ -34,7 +36,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public abstract class InstanceCreatingMarshaller<T> implements Marshallable {
|
||||
|
||||
private Class<T> tClass;
|
||||
private Type tClass;
|
||||
|
||||
/**
|
||||
* Constructor for use in subclasses.
|
||||
@@ -45,11 +47,19 @@ public abstract class InstanceCreatingMarshaller<T> implements Marshallable {
|
||||
this.tClass = tClass;
|
||||
}
|
||||
|
||||
protected InstanceCreatingMarshaller(Type tClass) {
|
||||
this.tClass = tClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class of objects deserialized.
|
||||
*/
|
||||
protected Class<T> tClass() {
|
||||
return tClass;
|
||||
return (Class<T>) tClass;
|
||||
}
|
||||
|
||||
protected Type tType() {
|
||||
return tClass;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +73,7 @@ public abstract class InstanceCreatingMarshaller<T> implements Marshallable {
|
||||
*/
|
||||
protected T createInstance() {
|
||||
try {
|
||||
return ObjectUtils.newInstance(tClass);
|
||||
return ObjectUtils.newInstance(tClass());
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Some of default marshallers, chosen for the type\n" +
|
||||
tClass + " by default, delegate to \n" +
|
||||
@@ -80,7 +90,7 @@ public abstract class InstanceCreatingMarshaller<T> implements Marshallable {
|
||||
@Override
|
||||
public void readMarshallable(@NotNull WireIn wireIn) {
|
||||
//noinspection unchecked
|
||||
tClass = wireIn.read(() -> "tClass").typeLiteral();
|
||||
tClass = wireIn.read(() -> "tClass").lenientTypeLiteral();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-3
@@ -20,13 +20,16 @@ import net.openhft.chronicle.hash.serialization.DataAccess;
|
||||
import net.openhft.chronicle.hash.serialization.SizedReader;
|
||||
import net.openhft.chronicle.hash.serialization.SizedWriter;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import static net.openhft.chronicle.hash.serialization.StatefulCopyable.copyIfNeeded;
|
||||
import static net.openhft.chronicle.hash.serialization.impl.DefaultElasticBytes.DEFAULT_BYTES_CAPACITY;
|
||||
|
||||
public class NotReusingSizedMarshallableDataAccess<T> extends SizedMarshallableDataAccess<T> {
|
||||
|
||||
public NotReusingSizedMarshallableDataAccess(
|
||||
Class<T> tClass, SizedReader<T> sizedReader, SizedWriter<? super T> sizedWriter) {
|
||||
super(tClass, sizedReader, sizedWriter);
|
||||
Type tClass, SizedReader<T> sizedReader, SizedWriter<? super T> sizedWriter) {
|
||||
super(tClass, sizedReader, sizedWriter, DEFAULT_BYTES_CAPACITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -37,6 +40,6 @@ public class NotReusingSizedMarshallableDataAccess<T> extends SizedMarshallableD
|
||||
@Override
|
||||
public DataAccess<T> copy() {
|
||||
return new NotReusingSizedMarshallableDataAccess<>(
|
||||
tClass(), copyIfNeeded(sizedReader()), copyIfNeeded(sizedWriter()));
|
||||
tType(), copyIfNeeded(sizedReader()), copyIfNeeded(sizedWriter()));
|
||||
}
|
||||
}
|
||||
|
||||
+7
-5
@@ -26,6 +26,8 @@ import net.openhft.chronicle.wire.WireOut;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import static net.openhft.chronicle.hash.serialization.StatefulCopyable.copyIfNeeded;
|
||||
import static net.openhft.chronicle.hash.serialization.impl.DefaultElasticBytes.DEFAULT_BYTES_CAPACITY;
|
||||
|
||||
@@ -52,8 +54,8 @@ public class SizedMarshallableDataAccess<T> extends InstanceCreatingMarshaller<T
|
||||
this(tClass, sizedReader, sizedWriter, DEFAULT_BYTES_CAPACITY);
|
||||
}
|
||||
|
||||
private SizedMarshallableDataAccess(
|
||||
Class<T> tClass, SizedReader<T> sizedReader, SizedWriter<? super T> sizedWriter,
|
||||
protected SizedMarshallableDataAccess(
|
||||
Type tClass, SizedReader<T> sizedReader, SizedWriter<? super T> sizedWriter,
|
||||
long bytesCapacity) {
|
||||
super(tClass);
|
||||
this.sizedWriter = sizedWriter;
|
||||
@@ -151,15 +153,15 @@ public class SizedMarshallableDataAccess<T> extends InstanceCreatingMarshaller<T
|
||||
@Override
|
||||
public DataAccess<T> copy() {
|
||||
return new SizedMarshallableDataAccess<>(
|
||||
tClass(), copyIfNeeded(sizedReader), copyIfNeeded(sizedWriter),
|
||||
tType(), copyIfNeeded(sizedReader), copyIfNeeded(sizedWriter),
|
||||
bytes.realCapacity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readMarshallable(@NotNull WireIn wireIn) {
|
||||
super.readMarshallable(wireIn);
|
||||
sizedReader = wireIn.read(() -> "sizedReader").typedMarshallable();
|
||||
sizedWriter = wireIn.read(() -> "sizedWriter").typedMarshallable();
|
||||
sizedReader = wireIn.read(() -> "sizedReader").object(SizedReader.class);
|
||||
sizedWriter = wireIn.read(() -> "sizedWriter").object(SizedWriter.class);
|
||||
initTransients(DEFAULT_BYTES_CAPACITY);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
@@ -207,5 +208,10 @@ public interface ChronicleMap<K, V> extends ConcurrentMap<K, V>,
|
||||
* @return the class of {@code <V>}
|
||||
*/
|
||||
Class<V> valueClass();
|
||||
|
||||
/**
|
||||
* @return the value Class or UnresolvedType if unknown.
|
||||
*/
|
||||
Type valueType();
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
@@ -73,7 +74,7 @@ public class VanillaChronicleMap<K, V, R>
|
||||
public transient DefaultValueProvider<K, V> defaultValueProvider;
|
||||
/////////////////////////////////////////////////
|
||||
// Value Data model
|
||||
Class<V> valueClass;
|
||||
Type valueClass;
|
||||
/////////////////////////////////////////////////
|
||||
// Behavior
|
||||
transient boolean putReturnsNull;
|
||||
@@ -116,7 +117,7 @@ public class VanillaChronicleMap<K, V, R>
|
||||
protected void readMarshallableFields(@NotNull WireIn wireIn) {
|
||||
super.readMarshallableFields(wireIn);
|
||||
|
||||
valueClass = wireIn.read(() -> "valueClass").typeLiteral();
|
||||
valueClass = wireIn.read(() -> "valueClass").lenientTypeLiteral();
|
||||
valueSizeMarshaller = wireIn.read(() -> "valueSizeMarshaller").object(SizeMarshaller.class);
|
||||
valueReader = wireIn.read(() -> "valueReader").object(SizedReader.class);
|
||||
valueDataAccess = wireIn.read(() -> "valueDataAccess").object(DataAccess.class);
|
||||
@@ -185,6 +186,7 @@ public class VanillaChronicleMap<K, V, R>
|
||||
}
|
||||
|
||||
public final V checkValue(Object value) {
|
||||
Class<V> valueClass = valueClass();
|
||||
if (!valueClass.isInstance(value)) {
|
||||
throw new ClassCastException(toIdentityString() + ": Value must be a " +
|
||||
valueClass.getName() + " but was a " + value.getClass());
|
||||
@@ -206,11 +208,21 @@ public class VanillaChronicleMap<K, V, R>
|
||||
|
||||
@Override
|
||||
public Class<K> keyClass() {
|
||||
return (Class<K>) keyClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type keyType() {
|
||||
return keyClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<V> valueClass() {
|
||||
return (Class<V>) valueClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type valueType() {
|
||||
return valueClass;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ public class EntryValueBytesData<V> extends AbstractData<V> {
|
||||
|
||||
@Stage("CachedEntryValue")
|
||||
private V cachedEntryValue =
|
||||
mh.m().valueClass() == CharSequence.class ? (V) new StringBuilder() : null;
|
||||
mh.m().valueType() == CharSequence.class ? (V) new StringBuilder() : null;
|
||||
@Stage("CachedEntryValue")
|
||||
private boolean cachedEntryValueRead = false;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import net.openhft.chronicle.map.VanillaChronicleMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
@@ -134,6 +135,11 @@ class SetFromMap<E> extends AbstractSet<E> implements ChronicleSet<E> {
|
||||
return m.keyClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type keyType() {
|
||||
return m.keyType();
|
||||
}
|
||||
|
||||
// TODO test queryContext methods
|
||||
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user