diff --git a/src/main/java/net/openhft/chronicle/map/Serializer.java b/src/main/java/net/openhft/chronicle/map/Serializer.java new file mode 100644 index 000000000..ec112db76 --- /dev/null +++ b/src/main/java/net/openhft/chronicle/map/Serializer.java @@ -0,0 +1,114 @@ +package net.openhft.chronicle.map; + +import net.openhft.chronicle.map.serialization.BytesReader; +import net.openhft.chronicle.map.serialization.MetaBytesWriter; +import net.openhft.chronicle.map.serialization.MetaProvider; +import net.openhft.chronicle.map.serialization.SizeMarshaller; +import net.openhft.chronicle.map.threadlocal.Provider; +import net.openhft.chronicle.map.threadlocal.ThreadLocalCopies; +import net.openhft.lang.io.Bytes; +import net.openhft.lang.io.serialization.BytesMarshallable; +import net.openhft.lang.io.serialization.ObjectFactory; +import net.openhft.lang.model.Byteable; +import net.openhft.lang.model.constraints.NotNull; + +/** + * uses a {@code SerializationBuilder} to readMarshallable and writeMarshallable objects + * @author Rob Austin. + */ +public class Serializer> + implements BytesMarshallable { + + final Class clazz; + final SizeMarshaller sizeMarshaller; + final BytesReader originalReader; + transient Provider> readerProvider; + final VW originalWriter; + transient Provider writerProvider; + final MVW originalMetaValueWriter; + final MetaProvider metaValueWriterProvider; + final ObjectFactory objectFactory; + + final ThreadLocal value = new ThreadLocal(); + + public Serializer(final SerializationBuilder serializationBuilder) { + + clazz = serializationBuilder.eClass; + sizeMarshaller = serializationBuilder.sizeMarshaller(); + originalReader = serializationBuilder.reader(); + + originalWriter = (VW) serializationBuilder.interop(); + originalMetaValueWriter = (MVW) serializationBuilder.metaInterop(); + metaValueWriterProvider = (MetaProvider) serializationBuilder.metaInteropProvider(); + objectFactory = serializationBuilder.factory(); + + readerProvider = Provider.of((Class) originalReader.getClass()); + writerProvider = Provider.of((Class) originalWriter.getClass()); + } + + + public O getObject() { + return value.get(); + } + + public void setObject(O value) { + this.value.set(value); + } + + @Override + public void readMarshallable(@NotNull Bytes in) throws IllegalStateException { + O o = readObject(in); + setObject(o); + } + + @Override + public void writeMarshallable(@NotNull Bytes out) { + O value1 = getObject(); + boolean byteableValue = value1 instanceof Byteable; + ThreadLocalCopies copies; + copies = readerProvider.getCopies(null); + VW valueWriter = writerProvider.get(copies, originalWriter); + copies = writerProvider.getCopies(copies); + long valueSize; + MetaBytesWriter metaValueWriter = null; + Byteable valueAsByteable = null; + + if (!byteableValue) { + copies = writerProvider.getCopies(copies); + valueWriter = writerProvider.get(copies, originalWriter); + copies = metaValueWriterProvider.getCopies(copies); + metaValueWriter = metaValueWriterProvider.get( + copies, originalMetaValueWriter, valueWriter, value1); + valueSize = metaValueWriter.size(valueWriter, value1); + } else { + valueAsByteable = (Byteable) value1; + valueSize = valueAsByteable.maxSize(); + } + + sizeMarshaller.writeSize(out, valueSize); + + + if (metaValueWriter != null) { + metaValueWriter.write(valueWriter, out, value1); + } else { + throw new UnsupportedOperationException(""); + } + } + + private O readObject(Bytes in) { + + ThreadLocalCopies copies; + copies = readerProvider.getCopies(null); + BytesReader valueReader = readerProvider.get(copies, originalReader); + + try { + final O v = objectFactory.create(); + long valueSize = sizeMarshaller.readSize(in); + return valueReader.read(in, valueSize, v); + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + +} diff --git a/src/test/java/net/openhft/chronicle/map/StatelessMapClientTest.java b/src/test/java/net/openhft/chronicle/map/SerializerTest.java similarity index 61% rename from src/test/java/net/openhft/chronicle/map/StatelessMapClientTest.java rename to src/test/java/net/openhft/chronicle/map/SerializerTest.java index 4b9e271f0..11bcfa046 100644 --- a/src/test/java/net/openhft/chronicle/map/StatelessMapClientTest.java +++ b/src/test/java/net/openhft/chronicle/map/SerializerTest.java @@ -6,54 +6,102 @@ import net.openhft.lang.io.Bytes; import net.openhft.lang.io.serialization.BytesMarshallable; import net.openhft.lang.model.constraints.NotNull; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; import java.io.*; import java.nio.ByteBuffer; import java.util.Collections; -public class StatelessMapClientTest extends TestCase { - +public class SerializerTest extends TestCase { @Test - public void testReadValueWriteIntegerValue() throws Exception { - testReadValueWriteValue("Test"); - testReadValueWriteValue(1); - testReadValueWriteValue(1L); - testReadValueWriteValue(1.0); - testReadValueWriteValue(1.0f); - testReadValueWriteValue(Collections.singleton("Test")); - testReadValueWriteValue(Collections.EMPTY_MAP); - testReadValueWriteValue(new MyTestClass(3)); - testReadValueWriteValue(new MyTestClassMarshallable(3)); - - testReadValueWriteValue(new MyTestClassExternalizable(3)); - testReadValueWriteValue(new MyTestClassObjectGraph(3)); - + public void testValueMarshallable() throws Exception { + testReadWriteValue("Test"); + testReadWriteValue(1); + testReadWriteValue(1L); + testReadWriteValue(1.0); + testReadWriteValue(1.0f); + testReadWriteValue(Collections.singleton("Test")); + testReadWriteValue(Collections.EMPTY_MAP); + testReadWriteValue(new MyTestClass(3)); + testReadWriteValue(new MyTestClassMarshallable(3)); + testReadWriteValue(new MyTestClassExternalizable(3)); + testReadWriteValue(new MyTestClassObjectGraph(3)); } - public void testReadValueWriteValue(Object value) throws Exception { + @Ignore + @Test + public void testKeyMarshallable() throws Exception { + testReadWriteKey("Test"); + testReadWriteKey(1); + testReadWriteKey(1L); + testReadWriteKey(1.0); + testReadWriteKey(1.0f); + testReadWriteKey(Collections.singleton("Test")); + testReadWriteKey(Collections.EMPTY_MAP); + testReadWriteKey(new MyTestClass(3)); + testReadWriteKey(new MyTestClassMarshallable(3)); + + testReadWriteKey(new MyTestClassExternalizable(3)); + testReadWriteKey(new MyTestClassObjectGraph(3)); + } + + + public void testReadWriteValue(Object value) throws Exception { Class valueClass = value.getClass(); - final ByteBufferBytes buffer = new ByteBufferBytes(ByteBuffer.allocateDirect(1024)); - ByteBufferBytes slice = buffer.slice(); + final ByteBufferBytes out = new ByteBufferBytes(ByteBuffer.allocateDirect(1024)); + ByteBufferBytes in = out.slice(); ChronicleMapBuilder builder = ChronicleMapBuilder.of(Integer.class, valueClass); builder.preMapConstruction(); - StatelessMapClient statelessMap = new StatelessMapClient(buffer, builder); + Serializer v = new Serializer(builder.valueBuilder); - statelessMap.writeValue(value); - long position = buffer.position(); - slice.limit(position); + v.setObject(value); + v.writeMarshallable(out); - Object actual = statelessMap.readValue(slice); + long position = out.position(); + in.limit(position); + + // let just blank the value so that we can test if it works + v.setObject(null); + + v.readMarshallable(in); + Object actual = v.getObject(); Assert.assertEquals(actual, value); } + public void testReadWriteKey(Object key) throws Exception { + + Class clazz = key.getClass(); + + final ByteBufferBytes out = new ByteBufferBytes(ByteBuffer.allocateDirect(1024)); + ByteBufferBytes in = out.slice(); + + ChronicleMapBuilder builder = ChronicleMapBuilder.of(clazz, Integer.class); + builder.preMapConstruction(); + + Serializer v = new Serializer(builder.keyBuilder); + + v.setObject(key); + v.writeMarshallable(out); + + long position = out.position(); + in.limit(position); + + // let just blank the value so that we can test if it works + v.setObject(null); + + v.readMarshallable(in); + Object actual = v.getObject(); + Assert.assertEquals(actual, key); + } + public static class MyTestClassExternalizable implements Externalizable { int a;