/******************************************************************************* * Copyright (c) 2010 Association for Decentralized Information Management in * Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.databoard.example.old; import gnu.trove.map.hash.TObjectIntHashMap; import java.awt.geom.Rectangle2D; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import org.simantics.databoard.Bindings; import org.simantics.databoard.Datatypes; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.error.BindingConstructionException; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.binding.error.DatatypeConstructionException; import org.simantics.databoard.serialization.SerializationException; import org.simantics.databoard.serialization.Serializer; import org.simantics.databoard.serialization.Serializer.NonRecursiveSerializer; import org.simantics.databoard.serialization.SerializerConstructionException; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.binary.BinaryReadable; import org.simantics.databoard.util.binary.BinaryWriteable; import org.simantics.databoard.util.binary.ByteBufferReadable; import org.simantics.databoard.util.binary.ByteBufferWriteable; /** * {@link Serializer} is a link between a {@link Binding} and a binary data. * {@link Binding#serializer(SerializationFormat)} creates Serializer object * which is based on the binding. Although the performance is good, it can be * improved by writing a taylored serializer by hand. *

* The example demonstrates how to write create hand-written * {@link Serializer} implementation to {@link Rectangle2D}. * * @author Toni Kalajainen */ public class SerializerExample3 { static class Rectangle2DSerializer extends NonRecursiveSerializer { public static final Rectangle2DSerializer INSTANCE = new Rectangle2DSerializer(); @Override public void serialize(DataOutput out, Object obj) throws IOException { Rectangle2D rect = (Rectangle2D) obj; out.writeDouble(rect.getX()); out.writeDouble(rect.getY()); out.writeDouble(rect.getWidth()); out.writeDouble(rect.getHeight()); } @Override public Object deserialize(DataInput in) throws IOException { double x = in.readDouble(); double y = in.readDouble(); double width = in.readDouble(); double height = in.readDouble(); return new Rectangle2D.Double(x, y, width, height); } @Override public void deserializeTo(DataInput in, Object obj) throws IOException { Rectangle2D.Double r = (Rectangle2D.Double) obj; r.x = in.readDouble(); r.y = in.readDouble(); r.width = in.readDouble(); r.height = in.readDouble(); } @Override public Integer getConstantSize() { return 8*4; } @Override public int getSize(Object obj) { return 8*4; } @Override public void skip(DataInput in) throws IOException { in.skipBytes(8*4); } @Override public int getMinSize() { return 8*4; } } public static void main(String[] args) throws IOException, SerializerConstructionException, SerializationException, BindingException, DatatypeConstructionException, BindingConstructionException { Datatype dataType = Datatypes.getDatatype(Rectangle2D.Double.class); System.out.println(dataType); Binding reflectionBinding = Bindings.getBinding(Rectangle2D.Double.class); Binding handWrittenBinding = new BindingExample.Rectangle2DBinding(); for (int i=0; i<10; i++) { System.out.println((i+1)+": Lets measure serialization performance... (1,000,000 serialization + deserialization)"); Serializer serializer1 = reflectionBinding.serializer(); Serializer serializer2 = handWrittenBinding.serializer(); Serializer serializer3 = Rectangle2DSerializer.INSTANCE; long time1 = getTime(serializer1); long time2 = getTime(serializer2); long time3 = getTime(serializer3); System.out.println("Time of Reflection Binding + Automatic Serializer: "+time1+" ms"); System.out.println("Time of Hand-Written Binding + Automatic Serializer: "+time2+" ms"); System.out.println("Time of Hand-Written Binding + Hand-Written Serializer: "+time3+" ms"); System.out.println(); } } static long getTime(Serializer serializer) throws IOException, SerializationException, BindingException { Rectangle2D rect = new Rectangle2D.Double(5, 5, 100, 200); TObjectIntHashMap identities = new TObjectIntHashMap(0); int size = serializer.getSize(rect, identities); identities.clear(); ByteBuffer data = ByteBuffer.allocate( size ); ArrayList identities2 = new ArrayList(); BinaryWriteable out = new ByteBufferWriteable(data); BinaryReadable in = new ByteBufferReadable(data); Runtime.getRuntime().gc(); long timeAtStart = System.currentTimeMillis(); for (int i=0; i<1000000; i++) { serializer.serialize(out, identities, rect); data.rewind(); serializer.deserialize(in, identities2); data.rewind(); } return System.currentTimeMillis() - timeAtStart; } }