Correctly initialize transient fields in marshallers

This commit is contained in:
leventov
2015-11-23 14:23:51 +03:00
parent b6fb3ecc62
commit bce834d2dc
19 changed files with 235 additions and 30 deletions
@@ -57,6 +57,7 @@ import static net.openhft.chronicle.hash.serialization.StatefulCopyable.copyIfNe
public class ListMarshaller<T>
implements BytesReader<List<T>>, BytesWriter<List<T>>, StatefulCopyable<ListMarshaller<T>> {
// Config fields
private final BytesReader<T> elementReader;
private final BytesWriter<? super T> elementWriter;
@@ -20,6 +20,8 @@ import net.openhft.chronicle.bytes.Bytes;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
@@ -49,12 +51,15 @@ public class MapMarshaller<K, V>
implements BytesReader<Map<K, V>>, BytesWriter<Map<K, V>>,
StatefulCopyable<MapMarshaller<K, V>> {
// Config fields
private final BytesReader<K> keyReader;
private final BytesWriter<? super K> keyWriter;
private final BytesReader<V> valueReader;
private final BytesWriter<? super V> valueWriter;
private final transient Deque<K> orderedKeys = new ArrayDeque<>();
private final transient Deque<V> orderedValues = new ArrayDeque<>();
// Cache fields
private transient Deque<K> orderedKeys;
private transient Deque<V> orderedValues;
public MapMarshaller(
BytesReader<K> keyReader, BytesWriter<? super K> keyWriter,
@@ -63,6 +68,17 @@ public class MapMarshaller<K, V>
this.keyWriter = keyWriter;
this.valueReader = valueReader;
this.valueWriter = valueWriter;
initTransients();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
private void initTransients() {
orderedKeys = new ArrayDeque<>();
orderedValues = new ArrayDeque<>();
}
@NotNull
@@ -20,6 +20,8 @@ import net.openhft.chronicle.bytes.Bytes;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.*;
import static net.openhft.chronicle.hash.serialization.StatefulCopyable.copyIfNeeded;
@@ -56,13 +58,26 @@ import static net.openhft.chronicle.hash.serialization.StatefulCopyable.copyIfNe
public class SetMarshaller<T>
implements BytesReader<Set<T>>, BytesWriter<Set<T>>, StatefulCopyable<SetMarshaller<T>> {
// Config fields
private final BytesReader<T> elementReader;
private final BytesWriter<? super T> elementWriter;
private final transient Deque<T> orderedElements = new ArrayDeque<>();
/** Cache field */
private transient Deque<T> orderedElements;
public SetMarshaller(BytesReader<T> elementReader, BytesWriter<? super T> elementWriter) {
this.elementReader = elementReader;
this.elementWriter = elementWriter;
initTransients();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
private void initTransients() {
orderedElements = new ArrayDeque<>();
}
@NotNull
@@ -24,10 +24,29 @@ import net.openhft.chronicle.hash.serialization.DataAccess;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ByteArrayDataAccess extends AbstractData<byte[]> implements DataAccess<byte[]> {
/** Cache field */
private transient HeapBytesStore<byte[]> bs;
/** State field */
private transient byte[] array;
private final transient HeapBytesStore<byte[]> bs = HeapBytesStore.uninitialized();
public ByteArrayDataAccess() {
initTransients();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
private void initTransients() {
bs = HeapBytesStore.uninitialized();
}
@Override
public RandomDataInput bytes() {
@@ -24,17 +24,37 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import sun.nio.ch.DirectBuffer;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.nio.ByteBuffer;
public class ByteBufferDataAccess extends AbstractData<ByteBuffer>
implements DataAccess<ByteBuffer> {
// Cache fields
private transient HeapBytesStore heapBytesStore;
private transient NativeBytesStore nativeBytesStore;
private transient VanillaBytes<Void> bytes;
// State fields
private transient ByteBuffer bb;
private final transient HeapBytesStore heapBytesStore = HeapBytesStore.uninitialized();
private final transient NativeBytesStore nativeBytesStore = NativeBytesStore.uninitialized();
final transient VanillaBytes<Void> bytes = VanillaBytes.vanillaBytes();
private transient BytesStore bytesStore;
public ByteBufferDataAccess() {
initTransients();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
private void initTransients() {
heapBytesStore = HeapBytesStore.uninitialized();
nativeBytesStore = NativeBytesStore.uninitialized();
bytes = VanillaBytes.vanillaBytes();
}
@Override
public RandomDataInput bytes() {
return bytesStore;
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable;
public class ByteableDataAccess<T extends Byteable> extends InstanceCreatingMarshaller<T>
implements DataAccess<T>, Data<T> {
/** State field */
private transient T instance;
public ByteableDataAccess(Class<T> tClass) {
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable;
public class BytesAsSizedReader<T>
implements SizedReader<T>, StatefulCopyable<BytesAsSizedReader<T>> {
/** Config field */
private final BytesReader<T> reader;
public BytesAsSizedReader(BytesReader<T> reader) {
@@ -24,14 +24,30 @@ import net.openhft.chronicle.hash.serialization.DataAccess;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.ObjectInputStream;
public class BytesMarshallableDataAccess<T extends BytesMarshallable>
extends InstanceCreatingMarshaller<T> implements DataAccess<T>, Data<T> {
transient T instance;
final transient Bytes bytes = Bytes.allocateElasticDirect(1);
/** Cache field */
private transient Bytes bytes;
/** State field */
private transient T instance;
public BytesMarshallableDataAccess(Class<T> tClass) {
super(tClass);
initTransients();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
private void initTransients() {
bytes = Bytes.allocateElasticDirect(1);
}
@Override
@@ -23,10 +23,27 @@ import net.openhft.chronicle.hash.serialization.StatefulCopyable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.ObjectInputStream;
public class CharSequenceSizedReader
implements SizedReader<CharSequence>, StatefulCopyable<CharSequenceSizedReader> {
private final transient StringBuilder sb = new StringBuilder();
/** Cache field */
private transient StringBuilder sb;
public CharSequenceSizedReader() {
initTransients();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
private void initTransients() {
sb = new StringBuilder();
}
@NotNull
@Override
@@ -20,6 +20,8 @@ import net.openhft.chronicle.bytes.Bytes;
import net.openhft.chronicle.hash.serialization.SizeMarshaller;
public final class ConstantSizeMarshaller implements SizeMarshaller {
/** Config field */
private final long constantSize;
public ConstantSizeMarshaller(long constantSize) {
@@ -25,21 +25,39 @@ import net.openhft.chronicle.hash.serialization.SizedReader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.ObjectInputStream;
import static net.openhft.chronicle.hash.serialization.StatefulCopyable.copyIfNeeded;
public class ExternalBytesMarshallableDataAccess<T> extends InstanceCreatingMarshaller<T>
implements DataAccess<T>, Data<T> {
// Config fields
private final SizedReader<T> reader;
private final BytesWriter<? super T> writer;
/** Cache field */
private transient Bytes bytes;
/** State field */
private transient T instance;
private final transient Bytes bytes = Bytes.allocateElasticDirect(1);
public ExternalBytesMarshallableDataAccess(
Class<T> tClass, SizedReader<T> reader, BytesWriter<? super T> writer) {
super(tClass);
this.writer = writer;
this.reader = reader;
initTransients();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
private void initTransients() {
bytes = Bytes.allocateElasticDirect(1);
}
@Override
@@ -28,6 +28,7 @@ import java.io.ObjectOutputStream;
public class ExternalizableDataAccess<T extends Externalizable> extends SerializableDataAccess<T> {
/** Config field */
protected final Class<T> tClass;
public ExternalizableDataAccess(Class<T> tClass) {
@@ -23,6 +23,7 @@ import net.openhft.chronicle.hash.serialization.SizedWriter;
import static net.openhft.chronicle.hash.serialization.StatefulCopyable.copyIfNeeded;
public class NotReusingSizedMarshallableDataAccess<T> extends SizedMarshallableDataAccess<T> {
public NotReusingSizedMarshallableDataAccess(
Class<T> tClass, SizedReader<T> sizedReader, SizedWriter<? super T> sizedWriter) {
super(tClass, sizedReader, sizedWriter);
@@ -29,10 +29,28 @@ import java.io.*;
public class SerializableDataAccess<T extends Serializable> extends AbstractData<T>
implements DataAccess<T> {
// Cache fields
transient Bytes bytes;
transient OutputStream out;
transient InputStream in;
/** State field */
transient T instance;
final transient Bytes bytes = Bytes.allocateElasticDirect(1);
final transient OutputStream out = bytes.outputStream();
final transient InputStream in = bytes.inputStream();
public SerializableDataAccess() {
initTransients();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
private void initTransients() {
bytes = Bytes.allocateElasticDirect(1);
out = bytes.outputStream();
in = bytes.inputStream();
}
@Override
public RandomDataInput bytes() {
@@ -25,21 +25,39 @@ import net.openhft.chronicle.hash.serialization.SizedWriter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.ObjectInputStream;
import static net.openhft.chronicle.hash.serialization.StatefulCopyable.copyIfNeeded;
public class SizedMarshallableDataAccess<T> extends InstanceCreatingMarshaller<T>
implements DataAccess<T>, Data<T> {
// Config fields
final SizedReader<T> sizedReader;
final SizedWriter<? super T> sizedWriter;
/** Cache field */
private transient Bytes bytes;
/** State field */
private transient T instance;
private final transient Bytes bytes = Bytes.allocateElasticDirect(1);
public SizedMarshallableDataAccess(
Class<T> tClass, SizedReader<T> sizedReader, SizedWriter<? super T> sizedWriter) {
super(tClass);
this.sizedWriter = sizedWriter;
this.sizedReader = sizedReader;
initTransients();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
private void initTransients() {
bytes = Bytes.allocateElasticDirect(1);
}
@Override
@@ -24,6 +24,9 @@ import net.openhft.chronicle.hash.serialization.StatefulCopyable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.ObjectInputStream;
/**
* {@link BytesReader} implementation for String, for the primary ChronicleMap's key of value type
* {@link StringSizedReader} + {@link CharSequenceSizedWriter} are more effective (because don't
@@ -35,7 +38,21 @@ import org.jetbrains.annotations.Nullable;
public class StringBytesReader
implements BytesReader<String>, StatefulCopyable<StringBytesReader> {
private final transient StringBuilder sb = new StringBuilder();
/** Cache field */
private transient StringBuilder sb;
public StringBytesReader() {
initTransients();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
private void initTransients() {
sb = new StringBuilder();
}
@NotNull
@Override
@@ -23,9 +23,25 @@ import net.openhft.chronicle.hash.serialization.StatefulCopyable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.ObjectInputStream;
public class StringSizedReader implements SizedReader<String>, StatefulCopyable<StringSizedReader> {
private final transient StringBuilder sb = new StringBuilder();
/** Cache field */
private transient StringBuilder sb;
public StringSizedReader() {
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
private void initTransients() {
sb = new StringBuilder();
}
@NotNull
@Override
@@ -33,11 +33,16 @@ import static net.openhft.chronicle.bytes.NativeBytesStore.nativeStoreWithFixedC
public class ValueDataAccess<T> extends AbstractData<T> implements DataAccess<T> {
/** The interface of values serialized. */
protected final Class<T> valueType;
private transient Byteable nativeInstance;
private transient Copyable nativeInstanceAsCopyable;
// Cache fields
protected transient Class<? extends T> nativeClass;
protected transient Class<? extends T> heapClass;
private transient Byteable nativeInstance;
private transient Copyable nativeInstanceAsCopyable;
/** State field */
private transient Byteable instance;
public ValueDataAccess(Class<T> valueType) {
@@ -45,6 +50,11 @@ public class ValueDataAccess<T> extends AbstractData<T> implements DataAccess<T>
initTransients();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
private void initTransients() {
nativeInstance = (Byteable) Values.newNativeReference(valueType);
nativeInstanceAsCopyable = (Copyable) nativeInstance;
@@ -54,11 +64,6 @@ public class ValueDataAccess<T> extends AbstractData<T> implements DataAccess<T>
0, nativeInstance.maxSize());
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
protected T createInstance() {
try {
return heapClass.newInstance();
@@ -32,9 +32,12 @@ import java.io.ObjectInputStream;
public class ValueReader<T>
implements SizedReader<T>, BytesReader<T>, StatefulCopyable<ValueReader<T>> {
/** The interface of values deserialized. */
protected final Class<T> valueType;
// Cache fields
protected transient Class<? extends T> heapClass;
private transient Class<? extends T> nativeClass;
protected transient Class<? extends T> nativeClass;
private transient Byteable nativeReference;
public ValueReader(Class<T> valueType) {
@@ -42,17 +45,17 @@ public class ValueReader<T>
initTransients();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
private void initTransients() {
heapClass = Values.heapClassFor(valueType);
nativeClass = Values.nativeClassFor(valueType);
nativeReference = (Byteable) Values.newNativeReference(valueType);
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initTransients();
}
protected T createInstance() {
try {
return heapClass.newInstance();