mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Improved support for BytesMarshallable and Marshallable, closes https://github.com/OpenHFT/Chronicle-Map/issues/235
This commit is contained in:
+3
-14
@@ -18,8 +18,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BytesMarshallableReaderWriter<V extends BytesMarshallable>
|
||||
extends InstanceCreatingMarshaller<V>
|
||||
implements SizedReader<V>, SizedWriter<V> {
|
||||
extends CachingCreatingMarshaller<V> {
|
||||
public BytesMarshallableReaderWriter(Class<V> vClass) {
|
||||
super(vClass);
|
||||
}
|
||||
@@ -39,17 +38,7 @@ public class BytesMarshallableReaderWriter<V extends BytesMarshallable>
|
||||
}
|
||||
|
||||
@Override
|
||||
public long size(@NotNull V toWrite) {
|
||||
Bytes<?> bytes = Wires.acquireBytes();
|
||||
toWrite.writeMarshallable(bytes);
|
||||
return bytes.readRemaining();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Bytes out, long size, @NotNull V toWrite) {
|
||||
VanillaBytes vanillaBytes = VANILLA_BYTES_TL.get();
|
||||
vanillaBytes.bytesStore(out, out.readPosition(), out.readRemaining());
|
||||
vanillaBytes.writeLimit(out.writePosition() + size);
|
||||
toWrite.writeMarshallable(vanillaBytes);
|
||||
protected void writeToWire(Wire wire, @NotNull V toWrite) {
|
||||
toWrite.writeMarshallable(wire.bytes());
|
||||
}
|
||||
}
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package net.openhft.chronicle.hash.serialization.impl;
|
||||
|
||||
import net.openhft.chronicle.bytes.Bytes;
|
||||
import net.openhft.chronicle.hash.serialization.SizedReader;
|
||||
import net.openhft.chronicle.hash.serialization.SizedWriter;
|
||||
import net.openhft.chronicle.wire.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class CachingCreatingMarshaller<V>
|
||||
extends InstanceCreatingMarshaller<V>
|
||||
implements SizedReader<V>, SizedWriter<V> {
|
||||
|
||||
static final ThreadLocal<Wire> WIRE_TL = ThreadLocal.withInitial(
|
||||
() -> WireType.BINARY_LIGHT.apply(Bytes.allocateElasticOnHeap(128)));
|
||||
static final ThreadLocal<Object> LAST_TL = new ThreadLocal<>();
|
||||
|
||||
public CachingCreatingMarshaller(Class<V> vClass) {
|
||||
super(vClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long size(@NotNull V toWrite) {
|
||||
Wire wire = WIRE_TL.get();
|
||||
wire.bytes().clear();
|
||||
writeToWire(wire, toWrite);
|
||||
LAST_TL.set(toWrite);
|
||||
return wire.bytes().readRemaining();
|
||||
}
|
||||
|
||||
protected abstract void writeToWire(Wire wire, @NotNull V toWrite);
|
||||
|
||||
@Override
|
||||
public void write(Bytes out, long size, @NotNull V toWrite) {
|
||||
if (LAST_TL.get() == toWrite) {
|
||||
Wire wire = WIRE_TL.get();
|
||||
if (wire.bytes().readRemaining() == size) {
|
||||
out.write(wire.bytes());
|
||||
wire.bytes().clear();
|
||||
LAST_TL.set(null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
BinaryWire wire = Wires.binaryWireForWrite(out, out.writePosition(), size);
|
||||
writeToWire(wire, toWrite);
|
||||
}
|
||||
}
|
||||
+2
-11
@@ -15,8 +15,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class MarshallableReaderWriter<V extends Marshallable>
|
||||
extends InstanceCreatingMarshaller<V>
|
||||
implements SizedReader<V>, SizedWriter<V> {
|
||||
extends CachingCreatingMarshaller<V> {
|
||||
public MarshallableReaderWriter(Class<V> vClass) {
|
||||
super(vClass);
|
||||
}
|
||||
@@ -32,15 +31,7 @@ public class MarshallableReaderWriter<V extends Marshallable>
|
||||
}
|
||||
|
||||
@Override
|
||||
public long size(@NotNull V toWrite) {
|
||||
Wire wire = Wires.acquireBinaryWire();
|
||||
toWrite.writeMarshallable(wire);
|
||||
return wire.bytes().readRemaining();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Bytes out, long size, @NotNull V toWrite) {
|
||||
BinaryWire wire = Wires.binaryWireForWrite(out, out.writePosition(), size);
|
||||
protected void writeToWire(Wire wire, @NotNull V toWrite) {
|
||||
toWrite.writeMarshallable(wire);
|
||||
}
|
||||
}
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019 Chronicle Software Ltd
|
||||
*/
|
||||
|
||||
package net.openhft.chronicle.hash.serialization.impl;
|
||||
|
||||
import net.openhft.chronicle.bytes.Bytes;
|
||||
import net.openhft.chronicle.hash.serialization.SizedReader;
|
||||
import net.openhft.chronicle.hash.serialization.SizedWriter;
|
||||
import net.openhft.chronicle.wire.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class TypedMarshallableReaderWriter<V extends Marshallable>
|
||||
extends CachingCreatingMarshaller<V> {
|
||||
|
||||
public TypedMarshallableReaderWriter(Class<V> vClass) {
|
||||
super(vClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public V read(Bytes in, long size, @Nullable V using) {
|
||||
BinaryWire wire = Wires.binaryWireForRead(in, in.readPosition(), size);
|
||||
return (V) wire.getValueIn().object(using, tClass());
|
||||
}
|
||||
protected void writeToWire(Wire wire, @NotNull V toWrite) {
|
||||
wire.getValueOut().object(toWrite);
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import net.openhft.chronicle.hash.serialization.*;
|
||||
import net.openhft.chronicle.hash.serialization.impl.BytesMarshallableReaderWriter;
|
||||
import net.openhft.chronicle.hash.serialization.impl.MarshallableReaderWriter;
|
||||
import net.openhft.chronicle.hash.serialization.impl.SerializationBuilder;
|
||||
import net.openhft.chronicle.hash.serialization.impl.TypedMarshallableReaderWriter;
|
||||
import net.openhft.chronicle.map.replication.MapRemoteOperations;
|
||||
import net.openhft.chronicle.set.ChronicleSetBuilder;
|
||||
import net.openhft.chronicle.values.ValueModel;
|
||||
@@ -49,6 +50,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileLock;
|
||||
@@ -136,7 +138,7 @@ import static net.openhft.chronicle.map.VanillaChronicleMap.alignAddr;
|
||||
*/
|
||||
public final class ChronicleMapBuilder<K, V> implements
|
||||
ChronicleHashBuilder<K, ChronicleMap<K, V>,
|
||||
ChronicleMapBuilder<K, V>> {
|
||||
ChronicleMapBuilder<K, V>> {
|
||||
|
||||
private static final int UNDEFINED_ALIGNMENT_CONFIG = -1;
|
||||
private static final int NO_ALIGNMENT = 1;
|
||||
@@ -265,7 +267,10 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
} else if (Marshallable.class.isAssignableFrom(valueClass)) {
|
||||
//noinspection unchecked
|
||||
builder.averageValueSize(1024)
|
||||
.valueMarshaller(new MarshallableReaderWriter<>((Class) valueClass));
|
||||
.valueMarshaller(
|
||||
valueClass.isMemberClass() && Modifier.isFinal(valueClass.getModifiers())
|
||||
? new MarshallableReaderWriter<>((Class) valueClass)
|
||||
: new TypedMarshallableReaderWriter<>((Class) valueClass));
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
@@ -274,14 +279,6 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
return Character.toLowerCase(name.charAt(0)) + name.substring(1);
|
||||
}
|
||||
|
||||
private boolean isKeySizeKnown() {
|
||||
return keyBuilder.sizeIsStaticallyKnown;
|
||||
}
|
||||
|
||||
private boolean isValueSizeKnown() {
|
||||
return valueBuilder.sizeIsStaticallyKnown;
|
||||
}
|
||||
|
||||
private static void checkSegments(final long segments) {
|
||||
if (segments <= 0) {
|
||||
throw new IllegalArgumentException("segments should be positive, " + segments + " given");
|
||||
@@ -359,7 +356,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
}
|
||||
|
||||
private static void writeNotComplete(@NotNull final FileChannel fileChannel,
|
||||
@NotNull final ByteBuffer headerBuffer,
|
||||
@NotNull final ByteBuffer headerBuffer,
|
||||
final int headerSize) throws IOException {
|
||||
//noinspection PointlessBitwiseExpression
|
||||
headerBuffer.putInt(SIZE_WORD_OFFSET, NOT_COMPLETE | DATA | headerSize);
|
||||
@@ -462,11 +459,63 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
return storedChecksum == checkSum;
|
||||
}
|
||||
|
||||
private static boolean isDefined(final double config) {
|
||||
return !isNaN(config);
|
||||
}
|
||||
|
||||
private static long toLong(final double v) {
|
||||
long l = round(v);
|
||||
if (l != v)
|
||||
throw new IllegalArgumentException("Integer argument expected, given " + v);
|
||||
return l;
|
||||
}
|
||||
|
||||
private static long roundUp(final double v) {
|
||||
return round(Math.ceil(v));
|
||||
}
|
||||
|
||||
private static long roundDown(final double v) {
|
||||
return (long) v;
|
||||
}
|
||||
|
||||
/**
|
||||
* When Chronicle Maps are created using {@link #createPersistedTo(File)} or
|
||||
* {@link #recoverPersistedTo(File, boolean)} or {@link
|
||||
* #createOrRecoverPersistedTo(File, boolean)} methods, file lock on the Chronicle Map's file is
|
||||
* acquired, that shouldn't be done from concurrent threads within the same JVM process. So
|
||||
* creation of Chronicle Maps persisted to the same File should be synchronized across JVM's
|
||||
* threads. Simple way would be to synchronize on some static (lock) object, but would serialize
|
||||
* all Chronicle Maps creations (persisted to any files), ConcurrentHashMap#compute() gives more
|
||||
* scalability. ConcurrentHashMap is used effectively for lock striping only, because the
|
||||
* entries are not even landing the map, because compute() always returns null.
|
||||
*/
|
||||
private static void fileLockedIO(@NotNull final File file,
|
||||
@NotNull final FileChannel fileChannel,
|
||||
@NotNull final FileIOAction fileIOAction) {
|
||||
FILE_LOCKING_CONTROL.compute(file, (k, v) -> {
|
||||
try {
|
||||
try (FileLock ignored = fileChannel.lock()) {
|
||||
fileIOAction.fileIOAction();
|
||||
}
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
throw Jvm.rethrow(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isKeySizeKnown() {
|
||||
return keyBuilder.sizeIsStaticallyKnown;
|
||||
}
|
||||
|
||||
private boolean isValueSizeKnown() {
|
||||
return valueBuilder.sizeIsStaticallyKnown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChronicleMapBuilder<K, V> clone() {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
final ChronicleMapBuilder<K, V> result = (ChronicleMapBuilder<K, V>) super.clone();
|
||||
@SuppressWarnings("unchecked") final ChronicleMapBuilder<K, V> result = (ChronicleMapBuilder<K, V>) super.clone();
|
||||
result.keyBuilder = keyBuilder.clone();
|
||||
result.valueBuilder = valueBuilder.clone();
|
||||
result.privateAPI = new ChronicleMapBuilderPrivateAPI<>(result);
|
||||
@@ -649,7 +698,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
public ChronicleMapBuilder<K, V> averageValue(@NotNull final V averageValue) {
|
||||
final Class<?> valueClass = averageValue.getClass();
|
||||
if (BytesMarshallable.class.isAssignableFrom(valueClass) &&
|
||||
valueBuilder.tClass.isInterface()) {
|
||||
(valueBuilder.tClass.isInterface() && valueBuilder.tClass != Marshallable.class)) {
|
||||
if (Serializable.class.isAssignableFrom(valueClass))
|
||||
LOG.warn("BytesMarshallable " + valueClass + " will be serialized as Serializable as the value class is an interface");
|
||||
else
|
||||
@@ -1568,7 +1617,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChronicleMap<K, V> recoverPersistedTo(@NotNull final File file, final boolean sameBuilderConfigAndLibraryVersion) throws IOException {
|
||||
public ChronicleMap<K, V> recoverPersistedTo(@NotNull final File file, final boolean sameBuilderConfigAndLibraryVersion) throws IOException {
|
||||
return recoverPersistedTo(file, sameBuilderConfigAndLibraryVersion,
|
||||
DEFAULT_CHRONICLE_MAP_CORRUPTION_LISTENER);
|
||||
}
|
||||
@@ -1576,7 +1625,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
@Override
|
||||
public ChronicleMap<K, V> recoverPersistedTo(@NotNull final File file,
|
||||
final boolean sameBuilderConfigAndLibraryVersion,
|
||||
@Nullable final ChronicleHashCorruption.Listener corruptionListener) throws IOException {
|
||||
@Nullable final ChronicleHashCorruption.Listener corruptionListener) throws IOException {
|
||||
return clone().createWithFile(file, true, sameBuilderConfigAndLibraryVersion, corruptionListener);
|
||||
}
|
||||
|
||||
@@ -1791,7 +1840,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
@NotNull final ChronicleHashResources resources,
|
||||
final boolean recover,
|
||||
final boolean overrideBuilderConfig,
|
||||
@Nullable final ChronicleHashCorruption.Listener corruptionListener) throws IOException {
|
||||
@Nullable final ChronicleHashCorruption.Listener corruptionListener) throws IOException {
|
||||
final ChronicleHashCorruptionImpl corruption = recover ? new ChronicleHashCorruptionImpl() : null;
|
||||
try {
|
||||
int headerSize = waitUntilReady(raf, file, recover);
|
||||
@@ -1967,49 +2016,4 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isDefined(final double config) {
|
||||
return !isNaN(config);
|
||||
}
|
||||
|
||||
private static long toLong(final double v) {
|
||||
long l = round(v);
|
||||
if (l != v)
|
||||
throw new IllegalArgumentException("Integer argument expected, given " + v);
|
||||
return l;
|
||||
}
|
||||
|
||||
private static long roundUp(final double v) {
|
||||
return round(Math.ceil(v));
|
||||
}
|
||||
|
||||
private static long roundDown(final double v) {
|
||||
return (long) v;
|
||||
}
|
||||
|
||||
/**
|
||||
* When Chronicle Maps are created using {@link #createPersistedTo(File)} or
|
||||
* {@link #recoverPersistedTo(File, boolean)} or {@link
|
||||
* #createOrRecoverPersistedTo(File, boolean)} methods, file lock on the Chronicle Map's file is
|
||||
* acquired, that shouldn't be done from concurrent threads within the same JVM process. So
|
||||
* creation of Chronicle Maps persisted to the same File should be synchronized across JVM's
|
||||
* threads. Simple way would be to synchronize on some static (lock) object, but would serialize
|
||||
* all Chronicle Maps creations (persisted to any files), ConcurrentHashMap#compute() gives more
|
||||
* scalability. ConcurrentHashMap is used effectively for lock striping only, because the
|
||||
* entries are not even landing the map, because compute() always returns null.
|
||||
*/
|
||||
private static void fileLockedIO(@NotNull final File file,
|
||||
@NotNull final FileChannel fileChannel,
|
||||
@NotNull final FileIOAction fileIOAction) {
|
||||
FILE_LOCKING_CONTROL.compute(file, (k, v) -> {
|
||||
try {
|
||||
try (FileLock ignored = fileChannel.lock()) {
|
||||
fileIOAction.fileIOAction();
|
||||
}
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
throw Jvm.rethrow(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package net.openhft.chronicle.map;
|
||||
|
||||
import net.openhft.chronicle.hash.serialization.impl.TypedMarshallableReaderWriter;
|
||||
import net.openhft.chronicle.wire.Marshallable;
|
||||
import net.openhft.chronicle.wire.SelfDescribingMarshallable;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -34,6 +36,19 @@ public final class AbstractMarshallableKeyValueTest {
|
||||
assertThat(map.get(new Key()).number, is(new Value().number));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAcceptAbstractMarshallableComponents2() throws Exception {
|
||||
final ChronicleMap<Key, Marshallable> map = ChronicleMapBuilder.of(Key.class, Marshallable.class).entries(10)
|
||||
.averageKey(new Key()).averageValue(new Value())
|
||||
.valueMarshaller(new TypedMarshallableReaderWriter<>(Marshallable.class))
|
||||
.create();
|
||||
|
||||
map.put(new Key(), new Value());
|
||||
|
||||
Value value = (Value) map.get(new Key());
|
||||
assertThat(value.number, is(new Value().number));
|
||||
}
|
||||
|
||||
private static final class Key extends SelfDescribingMarshallable {
|
||||
private String k = "key";
|
||||
}
|
||||
|
||||
@@ -468,7 +468,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
ChronicleMap c = newShmIntString();
|
||||
c.get(null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
ChronicleMap c = newShmIntString();
|
||||
c.containsKey(null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,7 +494,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
ChronicleMap c = newShmIntString();
|
||||
c.put(null, "whatever");
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,7 +507,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
ChronicleMap c = newShmIntString();
|
||||
c.put(JSR166TestCase.notPresent, null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
ChronicleMap c = newShmIntString();
|
||||
c.putIfAbsent(null, "whatever");
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,7 +568,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
ChronicleMap c = newShmIntString();
|
||||
c.replace(null, "whatever");
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,7 +581,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
ChronicleMap c = newShmIntString();
|
||||
c.replace(null, "A", "whatever");
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,7 +593,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
ChronicleMap c = newShmIntString(5);
|
||||
c.containsValue(null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}*/
|
||||
|
||||
@@ -606,7 +606,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
ChronicleMap c = newShmIntString(5);
|
||||
c.contains(null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -620,7 +620,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
ChronicleMap c = newShmIntString();
|
||||
c.putIfAbsent(JSR166TestCase.notPresent, null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,7 +633,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
ChronicleMap c = newShmIntString();
|
||||
c.replace(JSR166TestCase.notPresent, null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -646,7 +646,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
ChronicleMap c = newShmIntString();
|
||||
c.replace(JSR166TestCase.notPresent, null, "A");
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,7 +659,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
ChronicleMap c = newShmIntString();
|
||||
c.replace(JSR166TestCase.notPresent, "A", null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,7 +673,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
c.put("sadsdf", "asdads");
|
||||
c.remove(null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -687,7 +687,7 @@ public class ReplicatedChronicleMapTest extends JSR166TestCase {
|
||||
c.put("sadsdf", "asdads");
|
||||
c.remove(null, "whatever");
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException|IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.openhft.chronicle.map;
|
||||
|
||||
import net.openhft.chronicle.wire.BytesInBinaryMarshallable;
|
||||
import net.openhft.chronicle.wire.Marshallable;
|
||||
import net.openhft.chronicle.wire.SelfDescribingMarshallable;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -94,6 +95,26 @@ public class SerializableTest {
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2d() {
|
||||
ChronicleMap<Integer, Marshallable> map = ChronicleMapBuilder.simpleMapOf(Integer.class, Marshallable.class)
|
||||
.name("bar")
|
||||
.averageValueSize(1024)
|
||||
.entries(10)
|
||||
.create();
|
||||
|
||||
String expected = IntStream.range(0, 4096)
|
||||
.mapToObj(i -> i % 50 == 0 ? String.format("\n%04d", i) : "" + i % 10)
|
||||
.collect(Collectors.joining(""));
|
||||
|
||||
Bar2 value = new Bar2(expected);
|
||||
map.put(1, value);
|
||||
Bar2 bar2 = (Bar2) map.get(1);
|
||||
String actual = bar2.x;
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
public static class Foo implements Serializable {
|
||||
public String x;
|
||||
|
||||
|
||||
@@ -420,7 +420,7 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
try (ChronicleMap c = newShmIntString(8076)) {
|
||||
c.get(null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException | IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,7 +432,7 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
try (ChronicleMap c = newShmIntString(8076)) {
|
||||
c.containsKey(null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException | IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,7 +444,7 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
try (ChronicleMap c = newShmIntString(8076)) {
|
||||
c.put(null, "whatever");
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException | IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,7 +457,7 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
try (ChronicleMap c = newShmIntString(8076)) {
|
||||
c.put(notPresent, null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException | IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,7 +470,7 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
try (ChronicleMap c = newShmIntString(8076)) {
|
||||
c.putIfAbsent(null, "whatever");
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException | IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
try (ChronicleMap c = newShmIntString(8076)) {
|
||||
c.replace(null, "whatever");
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException | IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
try (ChronicleMap c = newShmIntString(8076)) {
|
||||
c.replace(null, "A", "whatever");
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException | IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,7 +508,7 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
try (ChronicleMap c = newShmIntString(8076)) {
|
||||
c.putIfAbsent(notPresent, null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException | IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
try (ChronicleMap c = newShmIntString(8076)) {
|
||||
c.replace(notPresent, null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException | IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,12 +528,11 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
* replace(x, null, y) throws NPE
|
||||
*/
|
||||
@Test(timeout = 5000)
|
||||
public void testReplaceValue2_NullPointerException
|
||||
() throws IOException {
|
||||
public void testReplaceValue2_NullPointerException() throws IOException {
|
||||
try (ChronicleMap c = newShmIntString(8076)) {
|
||||
c.replace(notPresent, null, "A");
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException | IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,7 +544,7 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
try (ChronicleMap c = newShmIntString(8076)) {
|
||||
c.replace(notPresent, "A", null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException | IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,7 +557,7 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
c.put("sadsdf", "asdads");
|
||||
c.remove(null);
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException | IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,7 +571,7 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
c.put("sadsdf", "asdads");
|
||||
c.remove(null, "whatever");
|
||||
shouldThrow();
|
||||
} catch (NullPointerException success) {
|
||||
} catch (NullPointerException | IllegalArgumentException success) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,6 +587,37 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPercentageComplete() {
|
||||
|
||||
try (ChronicleMap<Integer, Integer> map = ChronicleMap
|
||||
.of(Integer.class, Integer.class)
|
||||
.entries(1600)
|
||||
.actualSegments(3)
|
||||
.maxBloatFactor(2)
|
||||
.create()) {
|
||||
|
||||
long remainingAutoResizes = 0;
|
||||
short percentageFreeSpace = 0;
|
||||
try {
|
||||
for (int i = 0; ; i++) {
|
||||
|
||||
map.put(i, 0);
|
||||
remainingAutoResizes = map.remainingAutoResizes();
|
||||
percentageFreeSpace = map.percentageFreeSpace();
|
||||
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
if (e.getMessage().contains("Attempt to allocate")) {
|
||||
Assert.assertEquals(0, (int) remainingAutoResizes);
|
||||
Assert.assertTrue(percentageFreeSpace < 6);
|
||||
return;
|
||||
}
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// classes for testing Comparable fallbacks
|
||||
static class BI implements Comparable<BI> {
|
||||
private final int value;
|
||||
@@ -671,36 +701,5 @@ public class ChronicleMapTest extends JSR166TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPercentageComplete() {
|
||||
|
||||
try (ChronicleMap<Integer, Integer> map = ChronicleMap
|
||||
.of(Integer.class, Integer.class)
|
||||
.entries(1600)
|
||||
.actualSegments(3)
|
||||
.maxBloatFactor(2)
|
||||
.create()) {
|
||||
|
||||
long remainingAutoResizes = 0;
|
||||
short percentageFreeSpace = 0;
|
||||
try {
|
||||
for (int i = 0; ; i++) {
|
||||
|
||||
map.put(i, 0);
|
||||
remainingAutoResizes = map.remainingAutoResizes();
|
||||
percentageFreeSpace = map.percentageFreeSpace();
|
||||
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
if (e.getMessage().contains("Attempt to allocate")) {
|
||||
Assert.assertEquals(0, (int) remainingAutoResizes);
|
||||
Assert.assertTrue(percentageFreeSpace < 6);
|
||||
return;
|
||||
}
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user