mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Make key/value size discovery more defensive, inspired by #43
This commit is contained in:
@@ -34,6 +34,6 @@ public class KeyBytesInterop<K, KI, MKI extends MetaBytesInterop<K, ? super KI>>
|
||||
|
||||
public MKI keyMetaInterop(K key) {
|
||||
return hh.h().metaKeyInteropProvider.get(
|
||||
ch.copies, hh.h().originalMetaKeyInterop, keyInterop, key);
|
||||
ch.copies, hh.h().originalMetaKeyInterop, keyInterop, key, false);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-5
@@ -92,10 +92,10 @@ public abstract class CopyingMetaBytesInterop<E, W> extends BasicCopyingMetaByte
|
||||
@Override
|
||||
public CopyingMetaBytesInterop<E, M> get(
|
||||
ThreadLocalCopies copies,
|
||||
CopyingMetaBytesInterop<E, M> originalMetaWriter, M writer, E e) {
|
||||
CopyingMetaBytesInterop<E, M> originalMetaWriter, M writer, E e, boolean checked) {
|
||||
DirectBytesBuffer.ForBytesMarshaller forBytesMarshaller =
|
||||
provider.get(copies, originalMetaWriter.buffer()).forBytesMarshaller;
|
||||
forBytesMarshaller.init(writer, e, mutable, maxSize);
|
||||
forBytesMarshaller.init(writer, e, mutable, maxSize, checked);
|
||||
return forBytesMarshaller;
|
||||
}
|
||||
}
|
||||
@@ -115,11 +115,12 @@ public abstract class CopyingMetaBytesInterop<E, W> extends BasicCopyingMetaByte
|
||||
}
|
||||
|
||||
@Override
|
||||
public CopyingMetaBytesInterop<E, W> get(ThreadLocalCopies copies,
|
||||
CopyingMetaBytesInterop<E, W> originalMetaWriter, W writer, E e) {
|
||||
public CopyingMetaBytesInterop<E, W> get(
|
||||
ThreadLocalCopies copies, CopyingMetaBytesInterop<E, W> originalMetaWriter,
|
||||
W writer, E e, boolean checked) {
|
||||
DirectBytesBuffer.ForBytesWriter forBytesWriter =
|
||||
provider.get(copies, originalMetaWriter.buffer()).forBytesWriter;
|
||||
forBytesWriter.init(writer, e, mutable);
|
||||
forBytesWriter.init(writer, e, mutable, checked);
|
||||
return forBytesWriter;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -17,6 +17,7 @@
|
||||
package net.openhft.chronicle.hash.serialization.internal;
|
||||
|
||||
import net.openhft.chronicle.hash.serialization.BytesWriter;
|
||||
import net.openhft.lang.io.BoundsCheckingDirectBytes;
|
||||
import net.openhft.lang.io.Bytes;
|
||||
import net.openhft.lang.model.*;
|
||||
import net.openhft.lang.threadlocal.ThreadLocalCopies;
|
||||
@@ -40,8 +41,10 @@ public abstract class DataValueMetaBytesInterop<E>
|
||||
return e.equals(other);
|
||||
}
|
||||
|
||||
void init(BytesWriter<E> writer, E e, long size) {
|
||||
void init(BytesWriter<E> writer, E e, long size, boolean checked) {
|
||||
Bytes buffer = this.buffer.obtain(size, true);
|
||||
if (checked)
|
||||
buffer = new BoundsCheckingDirectBytes(buffer, null);
|
||||
writer.write(buffer, e);
|
||||
buffer.flip();
|
||||
assert buffer.remaining() == size;
|
||||
@@ -87,13 +90,13 @@ public abstract class DataValueMetaBytesInterop<E>
|
||||
@Override
|
||||
public MetaBytesInterop<E, BytesWriter<E>> get(
|
||||
ThreadLocalCopies copies, MetaBytesInterop<E, BytesWriter<E>> originalMetaWriter,
|
||||
BytesWriter<E> writer, E e) {
|
||||
BytesWriter<E> writer, E e, boolean checked) {
|
||||
if (e instanceof Byteable)
|
||||
return metaByteableInterop;
|
||||
DirectBytesBuffer.ForDataValueWriter forDataValueWriter =
|
||||
provider.get(copies, ((DataValueMetaBytesInterop)originalMetaWriter).buffer)
|
||||
.forDataValueWriter;
|
||||
forDataValueWriter.init(writer, e, size);
|
||||
forDataValueWriter.init(writer, e, size, checked);
|
||||
return forDataValueWriter;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -35,8 +35,9 @@ public final class DelegatingMetaBytesInteropProvider<E, I extends BytesInterop<
|
||||
private DelegatingMetaBytesInteropProvider() {}
|
||||
|
||||
@Override
|
||||
public MetaBytesInterop<E, I> get(ThreadLocalCopies copies,
|
||||
MetaBytesInterop<E, I> originalMetaWriter, I writer, E e) {
|
||||
public MetaBytesInterop<E, I> get(
|
||||
ThreadLocalCopies copies, MetaBytesInterop<E, I> originalMetaWriter, I writer, E e,
|
||||
boolean checked) {
|
||||
return originalMetaWriter;
|
||||
}
|
||||
|
||||
|
||||
+7
-5
@@ -17,9 +17,7 @@
|
||||
package net.openhft.chronicle.hash.serialization.internal;
|
||||
|
||||
import net.openhft.chronicle.hash.serialization.BytesWriter;
|
||||
import net.openhft.lang.io.Bytes;
|
||||
import net.openhft.lang.io.DirectBytes;
|
||||
import net.openhft.lang.io.DirectStore;
|
||||
import net.openhft.lang.io.*;
|
||||
import net.openhft.lang.io.serialization.BytesMarshallableSerializer;
|
||||
import net.openhft.lang.io.serialization.BytesMarshaller;
|
||||
import net.openhft.lang.io.serialization.ObjectSerializer;
|
||||
@@ -91,13 +89,15 @@ class DirectBytesBuffer
|
||||
super(DirectBytesBuffer.this);
|
||||
}
|
||||
|
||||
void init(M writer, E e, boolean mutable, long maxSize) {
|
||||
void init(M writer, E e, boolean mutable, long maxSize, boolean checked) {
|
||||
if (mutable || writer != this.writer || e != cur) {
|
||||
this.writer = writer;
|
||||
cur = e;
|
||||
while (true) {
|
||||
try {
|
||||
Bytes buffer = this.buffer.obtain(maxSize, true);
|
||||
if (checked)
|
||||
buffer = new BoundsCheckingDirectBytes(buffer, null);
|
||||
writer.write(buffer, e);
|
||||
buffer.flip();
|
||||
long size = this.size = buffer.remaining();
|
||||
@@ -122,12 +122,14 @@ class DirectBytesBuffer
|
||||
super(DirectBytesBuffer.this);
|
||||
}
|
||||
|
||||
void init(W writer, E e, boolean mutable) {
|
||||
void init(W writer, E e, boolean mutable, boolean checked) {
|
||||
if (mutable || writer != this.writer || e != cur) {
|
||||
this.writer = writer;
|
||||
cur = e;
|
||||
long size = writer.size(e);
|
||||
Bytes buffer = this.buffer.obtain(size, true);
|
||||
if (checked)
|
||||
buffer = new BoundsCheckingDirectBytes(buffer, null);
|
||||
writer.write(buffer, e);
|
||||
buffer.flip();
|
||||
this.size = size;
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.io.Serializable;
|
||||
|
||||
public interface MetaProvider<E, W, MW extends MetaBytesWriter<E, ? super W>> extends Serializable {
|
||||
|
||||
MW get(ThreadLocalCopies copies, MW originalMetaWriter, W writer, E e);
|
||||
MW get(ThreadLocalCopies copies, MW originalMetaWriter, W writer, E e, boolean checked);
|
||||
|
||||
ThreadLocalCopies getCopies(ThreadLocalCopies copies);
|
||||
}
|
||||
|
||||
+3
-2
@@ -278,7 +278,7 @@ public final class SerializationBuilder<E> implements Cloneable, Serializable {
|
||||
MetaProvider metaInteropProvider = this.metaInteropProvider;
|
||||
try {
|
||||
metaInterop = metaInteropProvider.get(
|
||||
copies, this.metaInterop, interop, sampleObject);
|
||||
copies, this.metaInterop, interop, sampleObject, true);
|
||||
break findSufficientSerializationSize;
|
||||
} catch (Exception e) {
|
||||
CopyingMetaBytesInterop.checkMaxSizeStillReasonable(maxSize, e);
|
||||
@@ -287,7 +287,8 @@ public final class SerializationBuilder<E> implements Cloneable, Serializable {
|
||||
}
|
||||
} else {
|
||||
MetaProvider metaInteropProvider = this.metaInteropProvider;
|
||||
metaInterop = metaInteropProvider.get(copies, this.metaInterop, interop, sampleObject);
|
||||
metaInterop = metaInteropProvider.get(
|
||||
copies, this.metaInterop, interop, sampleObject, true);
|
||||
}
|
||||
return metaInterop.size(interop, sampleObject);
|
||||
}
|
||||
|
||||
@@ -1329,7 +1329,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
MetaProvider metaWriterProvider = valueBuilder.metaInteropProvider();
|
||||
copies = metaWriterProvider.getCopies(copies);
|
||||
MetaBytesWriter metaValueWriter = metaWriterProvider.get(copies,
|
||||
valueBuilder.metaInterop(), valueWriter, defaultValue);
|
||||
valueBuilder.metaInterop(), valueWriter, defaultValue, true);
|
||||
return new ConstantValueProvider<>(defaultValue, metaValueWriter, valueWriter);
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,8 @@ final class WriterWithSize<T> {
|
||||
copies = writerProvider.getCopies(copies);
|
||||
Object writer = writerProvider.get(copies, originalWriter);
|
||||
copies = metaWriterProvider.getCopies(copies);
|
||||
MetaBytesWriter metaWriter = metaWriterProvider.get(copies, originalMetaWriter, writer, t);
|
||||
MetaBytesWriter metaWriter = metaWriterProvider.get(
|
||||
copies, originalMetaWriter, writer, t, false);
|
||||
long size = metaWriter.size(writer, t);
|
||||
if (bufferResizer != null)
|
||||
out = resizeIfRequired(out, size);
|
||||
@@ -90,7 +91,8 @@ final class WriterWithSize<T> {
|
||||
public ThreadLocalCopies writeInLoop(Bytes out, T t, Object writer,
|
||||
@Nullable ThreadLocalCopies copies) {
|
||||
copies = metaWriterProvider.getCopies(copies);
|
||||
MetaBytesWriter metaWriter = metaWriterProvider.get(copies, originalMetaWriter, writer, t);
|
||||
MetaBytesWriter metaWriter = metaWriterProvider.get(
|
||||
copies, originalMetaWriter, writer, t, false);
|
||||
long size = metaWriter.size(writer, t);
|
||||
if (bufferResizer != null)
|
||||
out = resizeIfRequired(out, size);
|
||||
|
||||
@@ -35,6 +35,6 @@ public class ValueBytesInterop<V, VI, MVI extends MetaBytesInterop<V, ? super VI
|
||||
|
||||
public MVI valueMetaInterop(V value) {
|
||||
return mh.m().metaValueInteropProvider.get(
|
||||
ch.copies, mh.m().originalMetaValueInterop, valueInterop, value);
|
||||
ch.copies, mh.m().originalMetaValueInterop, valueInterop, value, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user