Spliptted benchmark into sequential and concurrent versions

git-svn-id: https://svn.apache.org/repos/asf/directmemory/lightning/trunk@1405430 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lightning-core/pom.xml b/lightning-core/pom.xml
index 947c2c9..d1c74dd 100644
--- a/lightning-core/pom.xml
+++ b/lightning-core/pom.xml
@@ -50,12 +50,26 @@
       <groupId>com.carrotsearch</groupId>
       <artifactId>hppc</artifactId>
     </dependency>
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava</artifactId>
+      </dependency>
 
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>com.carrotsearch</groupId>
+      <artifactId>junit-benchmarks</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.h2database</groupId>
+      <artifactId>h2</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <profiles>
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/AbstractLightningBenchmark.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/AbstractLightningBenchmark.java
new file mode 100644
index 0000000..3a05a24
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/AbstractLightningBenchmark.java
@@ -0,0 +1,341 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.directmemory.lightning.base.AbstractObjectMarshaller;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.io.InputStreamSource;
+import org.apache.directmemory.lightning.io.OutputStreamTarget;
+import org.apache.directmemory.lightning.io.SerializerInputStream;
+import org.apache.directmemory.lightning.io.SerializerOutputStream;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.carrotsearch.junitbenchmarks.AbstractBenchmark;
+
+public abstract class AbstractLightningBenchmark
+    extends AbstractBenchmark
+{
+
+    private static Serializer serializer;
+
+    @BeforeClass
+    public static void initializeLightning()
+    {
+        long buildStartTime = System.nanoTime();
+        serializer =
+            Lightning.newBuilder().debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new BenchmarkSerializerDefinition() ).build();
+        long nanos = TimeUnit.NANOSECONDS.toMillis( System.nanoTime() - buildStartTime );
+        System.out.println( "Lightning Serializer build time: " + nanos + " ms" );
+    }
+
+    @Test
+    public void benchmarkLightningSerialization()
+        throws Exception
+    {
+        Foo foo = buildRandomFoo();
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        OutputStreamTarget target = new OutputStreamTarget( baos );
+        SerializerOutputStream out = new SerializerOutputStream( serializer, target );
+        out.writeObject( foo );
+        assertNotNull( baos.toByteArray() );
+    }
+
+    @Test
+    public void benchmarkLightningDeserialization()
+        throws Exception
+    {
+        Foo foo = buildRandomFoo();
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        OutputStreamTarget target = new OutputStreamTarget( baos );
+        SerializerOutputStream out = new SerializerOutputStream( serializer, target );
+        out.writeObject( foo );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        InputStreamSource source = new InputStreamSource( bais );
+        SerializerInputStream in = new SerializerInputStream( serializer, source );
+        Object value = in.readObject();
+        assertNotNull( value );
+        assertEquals( foo, value );
+    }
+
+    @Test
+    public void benchmarkJavaSerialization()
+        throws Exception
+    {
+        Foo foo = buildRandomFoo();
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream( baos );
+        out.writeObject( foo );
+        assertNotNull( baos.toByteArray() );
+    }
+
+    @Test
+    public void benchmarkJavaDeserialization()
+        throws Exception
+    {
+        Foo foo = buildRandomFoo();
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream( baos );
+        out.writeObject( foo );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        ObjectInputStream in = new ObjectInputStream( bais );
+        Object value = in.readObject();
+
+        assertNotNull( value );
+        assertEquals( foo, value );
+    }
+
+    private static final Random RANDOM = new Random( System.nanoTime() );
+
+    private static final String[] STRING_VALUES = { "HGHO", "jldu", "oösd", "JKGH", "HGFG", "JLHL", "GJJK", "JKGH" };
+
+    private static Foo buildRandomFoo()
+    {
+        Foo foo = new Foo();
+        foo.enumValue = RANDOM.nextInt( 100 ) < 50 ? Bar.Value1 : Bar.Value2;
+        foo.someOther = RANDOM.nextInt();
+        foo.value = RANDOM.nextInt( 100 ) < 50 ? null : RANDOM.nextInt();
+        foo.first = STRING_VALUES[RANDOM.nextInt( STRING_VALUES.length )];
+        foo.second = STRING_VALUES[RANDOM.nextInt( STRING_VALUES.length )];
+
+        return foo;
+    }
+
+    public static class BenchmarkSerializerDefinition
+        extends AbstractSerializerDefinition
+    {
+
+        @Override
+        protected void configure()
+        {
+            serialize( Foo.class ).attributes();
+        }
+    }
+
+    @SuppressWarnings( "serial" )
+    public static class Foo
+        implements Serializable
+    {
+
+        private String first;
+
+        private String second;
+
+        private Integer value;
+
+        private int someOther;
+
+        @Attribute
+        private Bar enumValue;
+
+        @Attribute
+        public String getFirst()
+        {
+            return first;
+        }
+
+        public void setFirst( String first )
+        {
+            this.first = first;
+        }
+
+        @Attribute
+        public String getSecond()
+        {
+            return second;
+        }
+
+        public void setSecond( String second )
+        {
+            this.second = second;
+        }
+
+        @Attribute
+        public Integer getValue()
+        {
+            return value;
+        }
+
+        public void setValue( Integer value )
+        {
+            this.value = value;
+        }
+
+        @Attribute
+        // Implicitly required
+        public int getSomeOther()
+        {
+            return someOther;
+        }
+
+        public void setSomeOther( int someOther )
+        {
+            this.someOther = someOther;
+        }
+
+        public Bar getEnumValue()
+        {
+            return enumValue;
+        }
+
+        public void setEnumValue( Bar enumValue )
+        {
+            this.enumValue = enumValue;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "Foo [hash=@" + hashCode() + ", first=" + first + ", second=" + second + ", value=" + value
+                + ", someOther=" + someOther + ", enumValue=" + enumValue + "]";
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( enumValue == null ) ? 0 : enumValue.hashCode() );
+            result = prime * result + ( ( first == null ) ? 0 : first.hashCode() );
+            result = prime * result + ( ( second == null ) ? 0 : second.hashCode() );
+            result = prime * result + someOther;
+            result = prime * result + ( ( value == null ) ? 0 : value.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            Foo other = (Foo) obj;
+            if ( enumValue != other.enumValue )
+                return false;
+            if ( first == null )
+            {
+                if ( other.first != null )
+                    return false;
+            }
+            else if ( !first.equals( other.first ) )
+                return false;
+            if ( second == null )
+            {
+                if ( other.second != null )
+                    return false;
+            }
+            else if ( !second.equals( other.second ) )
+                return false;
+            if ( someOther != other.someOther )
+                return false;
+            if ( value == null )
+            {
+                if ( other.value != null )
+                    return false;
+            }
+            else if ( !value.equals( other.value ) )
+                return false;
+            return true;
+        }
+    }
+
+    public static enum Bar
+    {
+        Value1, Value2
+    }
+
+    public static class BarMarshaller
+        extends AbstractObjectMarshaller
+    {
+
+        @Override
+        public boolean acceptType( Class<?> type )
+        {
+            return type == Bar.class;
+        }
+
+        @Override
+        public void marshall( Object value, PropertyDescriptor propertyDescriptor, Target target,
+                              SerializationContext serializationContext )
+            throws IOException
+        {
+        }
+
+        @Override
+        public <V> V unmarshall( V value, PropertyDescriptor propertyDescriptor, Source source,
+                                 SerializationContext serializationContext )
+            throws IOException
+        {
+
+            return null;
+        }
+    }
+
+    public static class SomeSpecialIntegerMarshaller
+        extends AbstractObjectMarshaller
+    {
+
+        @Override
+        public boolean acceptType( Class<?> type )
+        {
+            return type == Integer.class;
+        }
+
+        @Override
+        public void marshall( Object value, PropertyDescriptor propertyDescriptor, Target target,
+                              SerializationContext serializationContext )
+            throws IOException
+        {
+        }
+
+        @Override
+        public <V> V unmarshall( V value, PropertyDescriptor propertyDescriptor, Source source,
+                                 SerializationContext serializationContext )
+            throws IOException
+        {
+
+            return value;
+        }
+
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/ConcurrentLightningBenchmark.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/ConcurrentLightningBenchmark.java
new file mode 100644
index 0000000..b6db15b
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/ConcurrentLightningBenchmark.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import com.carrotsearch.junitbenchmarks.BenchmarkOptions;
+import com.carrotsearch.junitbenchmarks.Clock;
+import com.carrotsearch.junitbenchmarks.annotation.AxisRange;
+import com.carrotsearch.junitbenchmarks.annotation.BenchmarkMethodChart;
+
+@AxisRange( min = 0, max = 1 )
+@BenchmarkMethodChart( filePrefix = "concurrent-benchmark" )
+@BenchmarkOptions( benchmarkRounds = 4000000, warmupRounds = 200000, clock = Clock.NANO_TIME, concurrency = BenchmarkOptions.CONCURRENCY_AVAILABLE_CORES )
+public class ConcurrentLightningBenchmark
+    extends AbstractLightningBenchmark
+{
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/Benchmark.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/CustomBenchmark.java
similarity index 99%
rename from lightning-core/src/test/java/org/apache/directmemory/lightning/Benchmark.java
rename to lightning-core/src/test/java/org/apache/directmemory/lightning/CustomBenchmark.java
index 413b1fd..8aa2926 100644
--- a/lightning-core/src/test/java/org/apache/directmemory/lightning/Benchmark.java
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/CustomBenchmark.java
@@ -43,7 +43,7 @@
 import org.junit.Test;
 
 @Ignore
-public class Benchmark
+public class CustomBenchmark
 {
 
     private static final int WARMUP_ROUNDS = 100000;
@@ -188,6 +188,7 @@
     }
 
     @Test
+    @Ignore
     public void benchmarkJavaSerialization()
         throws Exception
     {
@@ -244,6 +245,7 @@
     }
 
     @Test
+    @Ignore
     public void benchmarkJavaDeserialization()
         throws Exception
     {
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/SequentialLightningBenchmark.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/SequentialLightningBenchmark.java
new file mode 100644
index 0000000..b645564
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/SequentialLightningBenchmark.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import com.carrotsearch.junitbenchmarks.BenchmarkOptions;
+import com.carrotsearch.junitbenchmarks.Clock;
+import com.carrotsearch.junitbenchmarks.annotation.AxisRange;
+import com.carrotsearch.junitbenchmarks.annotation.BenchmarkMethodChart;
+
+@AxisRange( min = 0, max = 1 )
+@BenchmarkMethodChart( filePrefix = "sequential-benchmark" )
+@BenchmarkOptions( benchmarkRounds = 2000000, warmupRounds = 200000, clock = Clock.NANO_TIME, concurrency = BenchmarkOptions.CONCURRENCY_SEQUENTIAL )
+public class SequentialLightningBenchmark
+    extends AbstractLightningBenchmark
+{
+}
diff --git a/pom.xml b/pom.xml
index 0a00ed0..06d92d3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,6 +66,7 @@
     <hppc.version>0.4.1</hppc.version>
     <asm.version>4.0</asm.version>
     <reflectasm.version>1.01</reflectasm.version>
+    <guava.version>13.0.1</guava.version>
 
     <junit.version>4.10</junit.version>
 
@@ -99,6 +100,11 @@
         <artifactId>hppc</artifactId>
         <version>${hppc.version}</version>
       </dependency>
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava</artifactId>
+        <version>${guava.version}</version>
+      </dependency>
 
       <dependency>
         <groupId>junit</groupId>
@@ -106,6 +112,18 @@
         <version>${junit.version}</version>
         <scope>test</scope>
       </dependency>
+      <dependency>
+        <groupId>com.carrotsearch</groupId>
+        <artifactId>junit-benchmarks</artifactId>
+        <version>0.4.0</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>com.h2database</groupId>
+        <artifactId>h2</artifactId>
+        <version>1.3.164</version>
+        <scope>test</scope>
+      </dependency>
       <!-- Core dependencies -->
 
       <!-- Integration dependencies -->