Merge asterix-experiments to master

Change-Id: I79b91e045bd056e62adb6e48795a6625baee0062
Reviewed-on: https://asterix-gerrit.ics.uci.edu/642
Reviewed-by: Ian Maxon <imaxon@apache.org>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/asterix-app/data/csv/sample_01.csv b/asterix-app/data/csv/sample_01.csv
index 4dd437a..fbba382 100644
--- a/asterix-app/data/csv/sample_01.csv
+++ b/asterix-app/data/csv/sample_01.csv
@@ -1,8 +1,8 @@
-1,0.899682764,5.6256,2013-08-07,07:22:35,1979-02-25T23:48:27.034

-2,0.669052398,,-1923-03-29,19:33:34,-1979-02-25T23:48:27.002

-3,0.572733058,192674,-1923-03-28,19:33:34,-1979-02-25T23:48:27.001

-4,,192674,-1923-03-27,19:33:34,-1979-02-25T23:48:27.001

-5,0.572733058,192674,,19:33:34,-1979-02-25T23:48:27.001

-6,0.572733058,192674,-1923-03-25,,-1979-02-25T23:48:27.001

-7,0.572733058,192674,-1923-03-24,19:33:34,

+1,0.899682764,5.6256,2013-08-07,07:22:35,1979-02-25T23:48:27.034
+2,0.669052398,,-1923-03-29,19:33:34,-1979-02-25T23:48:27.002
+3,0.572733058,192674,-1923-03-28,19:33:34,-1979-02-25T23:48:27.001
+4,,192674,-1923-03-27,19:33:34,-1979-02-25T23:48:27.001
+5,0.572733058,192674,,19:33:34,-1979-02-25T23:48:27.001
+6,0.572733058,192674,-1923-03-25,,-1979-02-25T23:48:27.001
+7,0.572733058,192674,-1923-03-24,19:33:34,
 8,,,,,
\ No newline at end of file
diff --git a/asterix-experiments/pom.xml b/asterix-experiments/pom.xml
new file mode 100644
index 0000000..9ed9324
--- /dev/null
+++ b/asterix-experiments/pom.xml
@@ -0,0 +1,165 @@
+<!--
+ ! Copyright 2009-2013 by The Regents of the University of California
+ ! Licensed 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 from
+ ! 
+ !     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.
+ !-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>asterix</artifactId>
+		<groupId>org.apache.asterix</groupId>
+		<version>0.8.8-SNAPSHOT</version>
+	</parent>
+	<artifactId>asterix-experiments</artifactId>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.0.2</version>
+				<configuration>
+					<source>1.7</source>
+					<target>1.7</target>
+					<fork>true</fork>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>appassembler-maven-plugin</artifactId>
+				<version>1.0</version>
+				<executions>
+					<execution>
+						<configuration>
+							<programs>
+								<program>
+									<mainClass>org.apache.asterix.experiment.client.LSMExperimentSetRunner</mainClass>
+									<name>lsmexprunner</name>
+								</program>
+								<program>
+									<mainClass>org.apache.asterix.experiment.client.SocketTweetGeneratorDriver</mainClass>
+									<name>datagenrunner</name>
+								</program>
+								<program>
+									<mainClass>org.apache.asterix.experiment.client.SpatialQueryGeneratorDriver</mainClass>
+									<name>querygenrunner</name>
+								</program>
+								<program>
+									<mainClass>org.apache.asterix.experiment.client.RecordCountingServer</mainClass>
+									<name>rcserver</name>
+								</program>
+							</programs>
+							<repositoryLayout>flat</repositoryLayout>
+							<repositoryName>lib</repositoryName>
+						</configuration>
+						<phase>package</phase>
+						<goals>
+							<goal>assemble</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<artifactId>maven-assembly-plugin</artifactId>
+				<version>2.2-beta-5</version>
+				<executions>
+					<execution>
+						<configuration>
+							<descriptors>
+								<descriptor>src/main/assembly/binary-assembly.xml</descriptor>
+							</descriptors>
+						</configuration>
+						<phase>package</phase>
+						<goals>
+							<goal>attached</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.asterix</groupId>
+			<artifactId>asterix-lang-common</artifactId>
+			<version>0.8.8-SNAPSHOT</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.asterix</groupId>
+			<artifactId>asterix-lang-aql</artifactId>
+			<version>0.8.8-SNAPSHOT</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.asterix</groupId>
+			<artifactId>asterix-algebra</artifactId>
+			<version>0.8.8-SNAPSHOT</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.asterix</groupId>
+			<artifactId>asterix-external-data</artifactId>
+			<version>0.8.8-SNAPSHOT</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.asterix</groupId>
+			<artifactId>asterix-metadata</artifactId>
+			<version>0.8.8-SNAPSHOT</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.httpcomponents</groupId>
+			<artifactId>httpclient</artifactId>
+			<version>4.2.2</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.httpcomponents</groupId>
+			<artifactId>httpcore</artifactId>
+			<version>4.2.2</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.8.1</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.hyracks</groupId>
+			<artifactId>hyracks-control-cc</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.hyracks</groupId>
+			<artifactId>hyracks-control-nc</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.asterix</groupId>
+			<artifactId>asterix-app</artifactId>
+			<version>0.8.8-SNAPSHOT</version>
+		</dependency>
+<!-- 		<dependency>
+			<groupId>net.schmizz</groupId>
+			<artifactId>sshj</artifactId>
+			<version>0.9.0</version>
+		</dependency> -->
+		<dependency>
+		  <groupId>com.hierynomus</groupId>
+		  <artifactId>sshj</artifactId>
+		  <version>0.13.0</version>
+		</dependency>
+	</dependencies>
+
+</project>
diff --git a/asterix-experiments/src/main/assembly/binary-assembly.xml b/asterix-experiments/src/main/assembly/binary-assembly.xml
new file mode 100644
index 0000000..ef74b9e
--- /dev/null
+++ b/asterix-experiments/src/main/assembly/binary-assembly.xml
@@ -0,0 +1,37 @@
+<!--
+ ! Copyright 2009-2013 by The Regents of the University of California
+ ! Licensed 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 from
+ ! 
+ !     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.
+ !-->
+<assembly>
+	<id>binary-assembly</id>
+	<formats>
+		<format>zip</format>
+		<format>dir</format>
+	</formats>
+	<includeBaseDirectory>false</includeBaseDirectory>
+	<fileSets>
+		<fileSet>
+			<directory>target/appassembler/bin</directory>
+			<outputDirectory>bin</outputDirectory>
+			<fileMode>0755</fileMode>
+		</fileSet>
+		<fileSet>
+			<directory>target/appassembler/lib</directory>
+			<outputDirectory>lib</outputDirectory>
+		</fileSet>
+		<fileSet>
+			<directory>src/main/resources/ingestion-experiment-binary-and-configs</directory>
+			<outputDirectory>.</outputDirectory>
+		</fileSet>
+	</fileSets>
+</assembly>
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/AbstractAction.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/AbstractAction.java
new file mode 100644
index 0000000..0e58dd4
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/AbstractAction.java
@@ -0,0 +1,45 @@
+/*
+ * 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.asterix.experiment.action.base;
+
+public abstract class AbstractAction implements IAction {
+
+    private final IExceptionListener el;
+
+    protected AbstractAction() {
+        el = new DefaultExceptionListener();
+    }
+
+    protected AbstractAction(IExceptionListener el) {
+        this.el = el;
+    }
+
+    @Override
+    public void perform() {
+        try {
+            doPerform();
+        } catch (Throwable t) {
+            el.caughtException(t);
+        }
+    }
+
+    protected abstract void doPerform() throws Exception;
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/DefaultExceptionListener.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/DefaultExceptionListener.java
new file mode 100644
index 0000000..5f89871
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/DefaultExceptionListener.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.action.base;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class DefaultExceptionListener implements IExceptionListener {
+
+    private static final Logger LOGGER = Logger.getLogger(DefaultExceptionListener.class.getName());
+
+    @Override
+    public void caughtException(Throwable t) {
+        if (LOGGER.isLoggable(Level.SEVERE)) {
+            LOGGER.severe("Caught exception: " + t);
+            LOGGER.severe("Stopping...");
+            t.printStackTrace();
+        }
+        System.exit(1);
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/IAction.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/IAction.java
new file mode 100644
index 0000000..c174a6f
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/IAction.java
@@ -0,0 +1,24 @@
+/*
+ * 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.asterix.experiment.action.base;
+
+public interface IAction {
+    public void perform();
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/IExceptionListener.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/IExceptionListener.java
new file mode 100644
index 0000000..e6a6cf1
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/IExceptionListener.java
@@ -0,0 +1,24 @@
+/*
+ * 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.asterix.experiment.action.base;
+
+public interface IExceptionListener {
+    public void caughtException(Throwable t);
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/ParallelActionSet.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/ParallelActionSet.java
new file mode 100644
index 0000000..9593307
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/ParallelActionSet.java
@@ -0,0 +1,75 @@
+/*
+ * 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.asterix.experiment.action.base;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class ParallelActionSet extends AbstractAction {
+
+    private final ExecutorService executor;
+
+    private final List<IAction> actions;
+
+    public ParallelActionSet() {
+        executor = Executors.newCachedThreadPool(new ThreadFactory() {
+
+            private final AtomicInteger tid = new AtomicInteger(0);
+
+            @Override
+            public Thread newThread(Runnable r) {
+                Thread t = new Thread(r);
+                t.setDaemon(true);
+                t.setName("ParallelActionThread " + tid.getAndIncrement());
+                return t;
+            }
+        });
+        actions = new ArrayList<>();
+    }
+
+    public void add(IAction action) {
+        actions.add(action);
+    }
+
+    @Override
+    protected void doPerform() throws Exception {
+        final Semaphore sem = new Semaphore(-(actions.size() - 1));
+        for (final IAction a : actions) {
+            executor.execute(new Runnable() {
+
+                @Override
+                public void run() {
+                    try {
+                        a.perform();
+                    } finally {
+                        sem.release();
+                    }
+                }
+            });
+        }
+        sem.acquire();
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/SequentialActionList.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/SequentialActionList.java
new file mode 100644
index 0000000..4f4e442
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/base/SequentialActionList.java
@@ -0,0 +1,42 @@
+/*
+ * 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.asterix.experiment.action.base;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SequentialActionList extends AbstractAction {
+    private final List<IAction> actions;
+
+    public SequentialActionList() {
+        actions = new ArrayList<>();
+    }
+
+    public void add(IAction exec) {
+        actions.add(exec);
+    }
+
+    @Override
+    protected void doPerform() throws Exception {
+        for (IAction e : actions) {
+            e.perform();
+        }
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/AbstractExecutableAction.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/AbstractExecutableAction.java
new file mode 100644
index 0000000..3f8a016
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/AbstractExecutableAction.java
@@ -0,0 +1,65 @@
+/*
+ * 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.asterix.experiment.action.derived;
+
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.commons.io.IOUtils;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.experiment.action.base.AbstractAction;
+
+public abstract class AbstractExecutableAction extends AbstractAction {
+
+    private static final Logger LOGGER = Logger.getLogger(AbstractExecutableAction.class.getName());
+
+    protected Map<String, String> getEnvironment() {
+        return Collections.<String, String> emptyMap();
+    }
+
+    protected abstract String getCommand();
+
+    protected abstract boolean doExecute(String command, Map<String, String> env) throws Exception;
+
+    protected abstract InputStream getErrorStream();
+
+    protected abstract InputStream getInputStream();
+
+    @Override
+    protected void doPerform() throws Exception {
+        StringWriter sw = new StringWriter();
+        String cmd = getCommand();
+        if (!doExecute(cmd, getEnvironment())) {
+            IOUtils.copy(getErrorStream(), sw);
+            throw new AsterixException("Error executing command: " + cmd + ".\n Error = " + sw.toString());
+        } else {
+            IOUtils.copy(getInputStream(), sw);
+            IOUtils.copy(getErrorStream(), sw);
+        }
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info(sw.toString());
+        }
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/AbstractLocalExecutableAction.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/AbstractLocalExecutableAction.java
new file mode 100644
index 0000000..1bba94f
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/AbstractLocalExecutableAction.java
@@ -0,0 +1,54 @@
+/*
+ * 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.asterix.experiment.action.derived;
+
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public abstract class AbstractLocalExecutableAction extends AbstractExecutableAction {
+
+    private final ProcessBuilder pb;
+
+    private Process p;
+
+    protected AbstractLocalExecutableAction() {
+        pb = new ProcessBuilder();
+    }
+
+    protected InputStream getErrorStream() {
+        return p == null ? null : p.getErrorStream();
+    }
+
+    protected InputStream getInputStream() {
+        return p == null ? null : p.getInputStream();
+    }
+
+    @Override
+    protected boolean doExecute(String command, Map<String, String> env) throws Exception {
+        List<String> cmd = Arrays.asList(command.split(" "));
+        pb.command(cmd);
+        pb.environment().putAll(env);
+        p = pb.start();
+        int exitVal = p.waitFor();
+        return exitVal == 0;
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/AbstractRemoteExecutableAction.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/AbstractRemoteExecutableAction.java
new file mode 100644
index 0000000..8976e7c
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/AbstractRemoteExecutableAction.java
@@ -0,0 +1,89 @@
+/*
+ * 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.asterix.experiment.action.derived;
+
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import net.schmizz.sshj.SSHClient;
+import net.schmizz.sshj.connection.channel.direct.Session;
+import net.schmizz.sshj.connection.channel.direct.Session.Command;
+
+public abstract class AbstractRemoteExecutableAction extends AbstractExecutableAction {
+
+    private final SSHClient client;
+
+    private final String hostname;
+
+    private final int port;
+
+    private final String username;
+
+    private final String keyLocation;
+
+    private Command cmd;
+
+    protected AbstractRemoteExecutableAction(String hostname, String username, String keyLocation) {
+        this(hostname, SSHClient.DEFAULT_PORT, username, keyLocation);
+    }
+
+    protected AbstractRemoteExecutableAction(String hostname, int port, String username, String keyLocation) {
+        this.hostname = hostname;
+        this.port = port;
+        this.username = username;
+        this.keyLocation = keyLocation;
+        client = new SSHClient();
+    }
+
+    protected InputStream getErrorStream() {
+        return cmd == null ? null : cmd.getErrorStream();
+    }
+
+    protected InputStream getInputStream() {
+        return cmd == null ? null : cmd.getInputStream();
+    }
+
+    @Override
+    protected boolean doExecute(String command, Map<String, String> env) throws Exception {
+        int exitVal = 0;
+        client.loadKnownHosts();
+        try {
+            client.connect(hostname, port);
+            client.authPublickey(username, keyLocation);
+            Session s = client.startSession();
+            try {
+                for (Entry<String, String> e : env.entrySet()) {
+                    s.setEnvVar(e.getKey(), e.getValue());
+                }
+                cmd = s.exec(command);
+                cmd.join();
+                Integer ev = cmd.getExitStatus();
+                exitVal = ev == null ? -1 : ev;
+                cmd.close();
+            } finally {
+                s.close();
+            }
+        } finally {
+            client.close();
+        }
+        return exitVal == 0;
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/CloseOutputStreamAction.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/CloseOutputStreamAction.java
new file mode 100644
index 0000000..66956f4
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/CloseOutputStreamAction.java
@@ -0,0 +1,40 @@
+/*
+ * 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.asterix.experiment.action.derived;
+
+import java.io.OutputStream;
+
+import org.apache.asterix.experiment.action.base.AbstractAction;
+import org.apache.hyracks.api.util.ExperimentProfilerUtils;
+
+public class CloseOutputStreamAction extends AbstractAction {
+
+    private final OutputStream os;
+
+    public CloseOutputStreamAction(OutputStream os) {
+        this.os = os;
+    }
+
+    @Override
+    protected void doPerform() throws Exception {
+        ExperimentProfilerUtils.closeOutputFile(os);
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/ManagixActions.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/ManagixActions.java
new file mode 100644
index 0000000..182cdbb
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/ManagixActions.java
@@ -0,0 +1,143 @@
+/*
+ * 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.asterix.experiment.action.derived;
+
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ManagixActions {
+
+    private enum ManagixCommand {
+        CONFIGURE("configure"),
+        CREATE("create", "-n", "-c", "-a"),
+        START("start", "-n"),
+        STOP("stop", "-n"),
+        DELETE("delete", "-n"),
+        LOG("log", "-n", "-d"),
+        SHUTDOWN("shutdown");
+
+        private final String cmdFormat;
+
+        private ManagixCommand(String name, String... options) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(name).append(" ");
+            if (options != null) {
+                for (int i = 0; i < options.length; ++i) {
+                    sb.append(options[i]).append(" ").append("{").append(i).append("}");
+                    if (i != options.length - 1) {
+                        sb.append(" ");
+                    }
+                }
+            }
+            cmdFormat = sb.toString();
+        }
+
+        public String getCommandFormat() {
+            return cmdFormat;
+        }
+    }
+
+    private static abstract class AbstractManagixCommandAction extends AbstractLocalExecutableAction {
+
+        private static final String cmdFormat = "{0}/bin/managix {1}";
+
+        private final String managixHomePath;
+
+        private final String command;
+
+        protected AbstractManagixCommandAction(String managixHomePath, String command) {
+            this.managixHomePath = managixHomePath;
+            this.command = command;
+        }
+
+        @Override
+        protected String getCommand() {
+            return MessageFormat.format(cmdFormat, managixHomePath, command);
+        }
+
+        @Override
+        protected Map<String, String> getEnvironment() {
+            Map<String, String> env = new HashMap<>();
+            env.put("MANAGIX_HOME", managixHomePath);
+            return env;
+        }
+
+    }
+
+    public static class ConfigureAsterixManagixAction extends AbstractManagixCommandAction {
+
+        public ConfigureAsterixManagixAction(String managixHomePath) {
+            super(managixHomePath, MessageFormat.format(ManagixCommand.CONFIGURE.getCommandFormat(), ""));
+        }
+
+    }
+
+    public static class CreateAsterixManagixAction extends AbstractManagixCommandAction {
+
+        public CreateAsterixManagixAction(String managixHomePath, String asterixInstanceName,
+                String clusterConfigFilePath, String asterixConfigFilePath) {
+            super(managixHomePath, MessageFormat.format(ManagixCommand.CREATE.getCommandFormat(), asterixInstanceName,
+                    clusterConfigFilePath, asterixConfigFilePath));
+        }
+
+    }
+
+    public static class StartAsterixManagixAction extends AbstractManagixCommandAction {
+
+        public StartAsterixManagixAction(String managixHomePath, String asterixInstanceName) {
+            super(managixHomePath, MessageFormat.format(ManagixCommand.START.getCommandFormat(), asterixInstanceName));
+        }
+
+    }
+
+    public static class StopAsterixManagixAction extends AbstractManagixCommandAction {
+
+        public StopAsterixManagixAction(String managixHomePath, String asterixInstanceName) {
+            super(managixHomePath, MessageFormat.format(ManagixCommand.STOP.getCommandFormat(), asterixInstanceName));
+        }
+
+    }
+
+    public static class DeleteAsterixManagixAction extends AbstractManagixCommandAction {
+
+        public DeleteAsterixManagixAction(String managixHomePath, String asterixInstanceName) {
+            super(managixHomePath, MessageFormat.format(ManagixCommand.DELETE.getCommandFormat(), asterixInstanceName));
+        }
+
+    }
+
+    public static class LogAsterixManagixAction extends AbstractManagixCommandAction {
+
+        public LogAsterixManagixAction(String managixHomePath, String asterixInstanceName, String destinationDir) {
+            super(managixHomePath, MessageFormat.format(ManagixCommand.LOG.getCommandFormat(), asterixInstanceName,
+                    destinationDir));
+        }
+
+    }
+
+    public static class ShutdownAsterixManagixAction extends AbstractManagixCommandAction {
+
+        public ShutdownAsterixManagixAction(String managixHomePath) {
+            super(managixHomePath, MessageFormat.format(ManagixCommand.SHUTDOWN.getCommandFormat(), ""));
+        }
+
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RemoteAsterixDriverKill.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RemoteAsterixDriverKill.java
new file mode 100644
index 0000000..44408e7
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RemoteAsterixDriverKill.java
@@ -0,0 +1,33 @@
+/*
+ * 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.asterix.experiment.action.derived;
+
+public class RemoteAsterixDriverKill extends AbstractRemoteExecutableAction {
+
+    public RemoteAsterixDriverKill(String hostname, String username, String keyLocation) {
+        super(hostname, username, keyLocation);
+    }
+
+    @Override
+    protected String getCommand() {
+        return "jps | awk '{if ($2 == \"NCDriver\" || $2 == \"CCDriver\") print $1;}' | xargs -n 1 kill -9";
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RemoteCopyFileAction.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RemoteCopyFileAction.java
new file mode 100644
index 0000000..6768e94
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RemoteCopyFileAction.java
@@ -0,0 +1,70 @@
+/*
+ * 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.asterix.experiment.action.derived;
+
+import net.schmizz.sshj.SSHClient;
+import net.schmizz.sshj.xfer.scp.SCPFileTransfer;
+import org.apache.asterix.experiment.action.base.AbstractAction;
+
+public class RemoteCopyFileAction extends AbstractAction {
+
+    private final String srcFilePath;
+
+    private final String destFilePath;
+
+    private final SSHClient client;
+
+    private final String hostname;
+
+    private final int port;
+
+    private final String username;
+
+    private final String keyLocation;
+
+    public RemoteCopyFileAction(String srcFilePath, String destFilePath, String hostname, String username,
+            String keyLocation) {
+        this(srcFilePath, destFilePath, hostname, SSHClient.DEFAULT_PORT, username, keyLocation);
+    }
+
+    public RemoteCopyFileAction(String srcFilePath, String destFilePath, String hostname, int port, String username,
+            String keyLocation) {
+        this.srcFilePath = srcFilePath;
+        this.destFilePath = destFilePath;
+        this.hostname = hostname;
+        this.port = port;
+        this.username = username;
+        this.keyLocation = keyLocation;
+        client = new SSHClient();
+    }
+
+    @Override
+    protected void doPerform() throws Exception {
+        client.loadKnownHosts();
+        try {
+            client.connect(hostname, port);
+            client.authPublickey(username, keyLocation);
+            SCPFileTransfer scpft = client.newSCPFileTransfer();
+            scpft.upload(srcFilePath, destFilePath);
+        } finally {
+            client.close();
+        }
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RunAQLFileAction.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RunAQLFileAction.java
new file mode 100644
index 0000000..2e6772a
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RunAQLFileAction.java
@@ -0,0 +1,98 @@
+/*
+ * 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.asterix.experiment.action.derived;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.text.MessageFormat;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.asterix.experiment.action.base.AbstractAction;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHeaders;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+
+public class RunAQLFileAction extends AbstractAction {
+    private final Logger LOGGER = Logger.getLogger(RunAQLFileAction.class.getName());
+    private static final String REST_URI_TEMPLATE = "http://{0}:{1}/aql";
+
+    private final HttpClient httpClient;
+
+    private final Path aqlFilePath;
+
+    private final String restHost;
+
+    private final int restPort;
+
+    private final OutputStream os;
+
+    public RunAQLFileAction(HttpClient httpClient, String restHost, int restPort, Path aqlFilePath) {
+        this.httpClient = httpClient;
+        this.aqlFilePath = aqlFilePath;
+        this.restHost = restHost;
+        this.restPort = restPort;
+        os = null;
+    }
+
+    public RunAQLFileAction(HttpClient httpClient, String restHost, int restPort, Path aqlFilePath, OutputStream os) {
+        this.httpClient = httpClient;
+        this.aqlFilePath = aqlFilePath;
+        this.restHost = restHost;
+        this.restPort = restPort;
+        this.os = os;
+    }
+
+    @Override
+    public void doPerform() throws Exception {
+        String aql = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(Files.readAllBytes(aqlFilePath))).toString();
+        String uri = MessageFormat.format(REST_URI_TEMPLATE, restHost, String.valueOf(restPort));
+        HttpPost post = new HttpPost(uri);
+        post.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
+        post.setEntity(new StringEntity(aql, StandardCharsets.UTF_8));
+        HttpEntity entity = httpClient.execute(post).getEntity();
+        if (entity != null && entity.isStreaming()) {
+            printStream(entity.getContent());
+        }
+        if (aql.contains("compact")) {
+            if (LOGGER.isLoggable(Level.INFO)) {
+                LOGGER.info("Compaction has been completed");
+            }
+        }
+    }
+
+    private void printStream(InputStream content) throws IOException {
+        if (os == null) {
+            IOUtils.copy(content, System.out);
+            System.out.flush();
+        } else {
+            IOUtils.copy(content, os);
+            os.flush();
+        }
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RunAQLStringAction.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RunAQLStringAction.java
new file mode 100644
index 0000000..1785e75
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RunAQLStringAction.java
@@ -0,0 +1,86 @@
+/*
+ * 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.asterix.experiment.action.derived;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.text.MessageFormat;
+
+import org.apache.asterix.experiment.action.base.AbstractAction;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHeaders;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+
+public class RunAQLStringAction extends AbstractAction {
+    private static final String REST_URI_TEMPLATE = "http://{0}:{1}/aql";
+
+    private final HttpClient httpClient;
+
+    private final String aql;
+
+    private final String restHost;
+
+    private final int restPort;
+
+    private final OutputStream os;
+
+    public RunAQLStringAction(HttpClient httpClient, String restHost, int restPort, String aql) {
+        this.httpClient = httpClient;
+        this.aql = aql;
+        this.restHost = restHost;
+        this.restPort = restPort;
+        os = null;
+    }
+
+    public RunAQLStringAction(HttpClient httpClient, String restHost, int restPort, String aql, OutputStream os) {
+        this.httpClient = httpClient;
+        this.aql = aql;
+        this.restHost = restHost;
+        this.restPort = restPort;
+        this.os = os;
+    }
+
+    @Override
+    public void doPerform() throws Exception {
+        String uri = MessageFormat.format(REST_URI_TEMPLATE, restHost, String.valueOf(restPort));
+        HttpPost post = new HttpPost(uri);
+        post.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
+        post.setEntity(new StringEntity(aql, StandardCharsets.UTF_8));
+        HttpEntity entity = httpClient.execute(post).getEntity();
+        if (entity != null && entity.isStreaming()) {
+            printStream(entity.getContent());
+        }
+    }
+
+    private void printStream(InputStream content) throws IOException {
+        if (os == null) {
+            IOUtils.copy(content, System.out);
+            System.out.flush();
+        } else {
+            IOUtils.copy(content, os);
+            os.flush();
+        }
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RunRESTIOWaitAction.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RunRESTIOWaitAction.java
new file mode 100644
index 0000000..9646d32
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/RunRESTIOWaitAction.java
@@ -0,0 +1,54 @@
+/*
+ * 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.asterix.experiment.action.derived;
+
+import java.text.MessageFormat;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.util.EntityUtils;
+
+import org.apache.asterix.experiment.action.base.AbstractAction;
+
+public class RunRESTIOWaitAction extends AbstractAction {
+    private static final String REST_URI_TEMPLATE = "http://{0}:{1}/iowait";
+
+    private final HttpClient httpClient;
+
+    private final String restHost;
+
+    private final int restPort;
+
+    public RunRESTIOWaitAction(HttpClient httpClient, String restHost, int restPort) {
+        this.httpClient = httpClient;
+        this.restHost = restHost;
+        this.restPort = restPort;
+    }
+
+    @Override
+    public void doPerform() throws Exception {
+        String uri = MessageFormat.format(REST_URI_TEMPLATE, restHost, String.valueOf(restPort));
+        HttpGet get = new HttpGet(uri);
+        HttpEntity entity = httpClient.execute(get).getEntity();
+        EntityUtils.consume(entity);
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/SleepAction.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/SleepAction.java
new file mode 100644
index 0000000..5200c8b
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/SleepAction.java
@@ -0,0 +1,37 @@
+/*
+ * 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.asterix.experiment.action.derived;
+
+import org.apache.asterix.experiment.action.base.AbstractAction;
+
+public class SleepAction extends AbstractAction {
+
+    private final long ms;
+
+    public SleepAction(long ms) {
+        this.ms = ms;
+    }
+
+    @Override
+    protected void doPerform() throws Exception {
+        Thread.sleep(ms);
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/StartDataGeneratorAction.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/StartDataGeneratorAction.java
new file mode 100644
index 0000000..f0d51ac
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/StartDataGeneratorAction.java
@@ -0,0 +1,53 @@
+/*
+ * 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.asterix.experiment.action.derived;
+
+import java.io.StringWriter;
+
+import net.schmizz.sshj.SSHClient;
+import net.schmizz.sshj.connection.channel.direct.Session;
+import net.schmizz.sshj.connection.channel.direct.Session.Command;
+
+import org.apache.commons.io.IOUtils;
+
+import org.apache.asterix.experiment.action.base.AbstractAction;
+
+public class StartDataGeneratorAction extends AbstractAction {
+
+    @Override
+    protected void doPerform() throws Exception {
+    }
+
+    public static void main(String[] args) throws Exception {
+        SSHClient sshClient = new SSHClient();
+        sshClient.loadKnownHosts();
+        sshClient.connect("asterix-1.ics.uci.edu");
+        sshClient.authPublickey("zheilbro", "/Users/zheilbron/.ssh/id_rsa");
+        Session session = sshClient.startSession();
+        Command lsCmd = session.exec("ls");
+        StringWriter sw = new StringWriter();
+        IOUtils.copy(lsCmd.getInputStream(), sw);
+        IOUtils.copy(lsCmd.getErrorStream(), sw);
+        System.out.println(sw.toString());
+        session.close();
+        sw.close();
+        sshClient.close();
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/TimedAction.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/TimedAction.java
new file mode 100644
index 0000000..f0e7ad7
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/action/derived/TimedAction.java
@@ -0,0 +1,61 @@
+/*
+ * 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.asterix.experiment.action.derived;
+
+import java.io.OutputStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.asterix.experiment.action.base.AbstractAction;
+import org.apache.asterix.experiment.action.base.IAction;
+
+public class TimedAction extends AbstractAction {
+
+    private final Logger LOGGER = Logger.getLogger(TimedAction.class.getName());
+
+    private final IAction action;
+    private final OutputStream os;
+
+    public TimedAction(IAction action) {
+        this.action = action;
+        os = null;
+    }
+
+    public TimedAction(IAction action, OutputStream os) {
+        this.action = action;
+        this.os = os;
+    }
+
+    @Override
+    protected void doPerform() throws Exception {
+        long start = System.currentTimeMillis();
+        action.perform();
+        long end = System.currentTimeMillis();
+        if (LOGGER.isLoggable(Level.SEVERE)) {
+            if (os == null) {
+                System.out.println("Elapsed time = " + (end - start) + " for action " + action);
+                System.out.flush();
+            } else {
+                os.write(("Elapsed time = " + (end - start) + " for action " + action).getBytes());
+                os.flush();
+            }
+        }
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment1Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment1Builder.java
new file mode 100644
index 0000000..4461fd7
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment1Builder.java
@@ -0,0 +1,40 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public abstract class AbstractExperiment1Builder extends AbstractLSMBaseExperimentBuilder {
+
+    public AbstractExperiment1Builder(String name, LSMExperimentSetRunnerConfig config, String clusterConfigFileName,
+            String ingestFileName, String dgenFileName) {
+        super(name, config, clusterConfigFileName, ingestFileName, dgenFileName, "count.aql");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("1.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment2ABuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment2ABuilder.java
new file mode 100644
index 0000000..4dce1af
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment2ABuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public abstract class AbstractExperiment2ABuilder extends AbstractLSMBaseExperimentBuilder {
+
+    public AbstractExperiment2ABuilder(String name, LSMExperimentSetRunnerConfig config, String clusterConfigFileName,
+            String ingestFileName, String dgenFileName) {
+        super(name, config, clusterConfigFileName, ingestFileName, dgenFileName, "count.aql");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("2_a.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment2BBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment2BBuilder.java
new file mode 100644
index 0000000..2aeb6f8
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment2BBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public abstract class AbstractExperiment2BBuilder extends AbstractLSMBaseExperimentBuilder {
+
+    public AbstractExperiment2BBuilder(String name, LSMExperimentSetRunnerConfig config, String clusterConfigFileName,
+            String ingestFileName, String dgenFileName) {
+        super(name, config, clusterConfigFileName, ingestFileName, dgenFileName, "count.aql");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("2_b.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment2CBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment2CBuilder.java
new file mode 100644
index 0000000..f54c78a
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment2CBuilder.java
@@ -0,0 +1,45 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public abstract class AbstractExperiment2CBuilder extends AbstractLSMBaseExperimentBuilder {
+
+    public AbstractExperiment2CBuilder(String name, LSMExperimentSetRunnerConfig config, String clusterConfigFileName,
+            String ingestFileName, String dgenFileName) {
+        super(name, config, clusterConfigFileName, ingestFileName, dgenFileName, "count.aql");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("2_c.aql")));
+    }
+
+    @Override
+    protected void doPost(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("avg_gram_tokens.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment2DBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment2DBuilder.java
new file mode 100644
index 0000000..f54b523
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment2DBuilder.java
@@ -0,0 +1,45 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public abstract class AbstractExperiment2DBuilder extends AbstractLSMBaseExperimentBuilder {
+
+    public AbstractExperiment2DBuilder(String name, LSMExperimentSetRunnerConfig config, String clusterConfigFileName,
+            String ingestFileName, String dgenFileName) {
+        super(name, config, clusterConfigFileName, ingestFileName, dgenFileName, "count.aql");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("2_d.aql")));
+    }
+
+    @Override
+    protected void doPost(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("avg_keyword_tokens.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment3Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment3Builder.java
new file mode 100644
index 0000000..f5fb4a4
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment3Builder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public abstract class AbstractExperiment3Builder extends AbstractLSMBaseExperimentBuilder {
+
+    public AbstractExperiment3Builder(String name, LSMExperimentSetRunnerConfig config, String clusterConfigFileName,
+            String ingestFileName, String dgenFileName) {
+        super(name, config, clusterConfigFileName, ingestFileName, dgenFileName, "count.aql");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("3.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment4Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment4Builder.java
new file mode 100644
index 0000000..e18975c
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment4Builder.java
@@ -0,0 +1,29 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public abstract class AbstractExperiment4Builder extends AbstractLSMBaseExperimentBuilder {
+
+    public AbstractExperiment4Builder(String name, LSMExperimentSetRunnerConfig config) {
+        super(name, config, "8node.xml", "base_8_ingest.aql", "8.dgen", "count.aql");
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment6Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment6Builder.java
new file mode 100644
index 0000000..a34e089
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment6Builder.java
@@ -0,0 +1,29 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public abstract class AbstractExperiment6Builder extends AbstractLSMBaseExperimentBuilder {
+
+    public AbstractExperiment6Builder(String name, LSMExperimentSetRunnerConfig config) {
+        super(name, config, "8node.xml", "base_8_ingest.aql", "8.dgen", "count.aql");
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment7Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment7Builder.java
new file mode 100644
index 0000000..d955167
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment7Builder.java
@@ -0,0 +1,189 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import org.apache.commons.lang3.StringUtils;
+
+import org.apache.asterix.experiment.action.base.AbstractAction;
+import org.apache.asterix.experiment.action.base.IAction;
+import org.apache.asterix.experiment.action.base.ParallelActionSet;
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.AbstractRemoteExecutableAction;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.action.derived.RunAQLStringAction;
+import org.apache.asterix.experiment.action.derived.RunRESTIOWaitAction;
+import org.apache.asterix.experiment.action.derived.SleepAction;
+import org.apache.asterix.experiment.action.derived.TimedAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+import org.apache.asterix.experiment.client.OrchestratorServer7;
+import org.apache.asterix.experiment.client.OrchestratorServer7.IProtocolActionBuilder;
+
+public abstract class AbstractExperiment7Builder extends AbstractLSMBaseExperimentBuilder {
+
+    private static final long DOMAIN_SIZE = (1L << 32);
+
+    public static final long QUERY_BEGIN_ROUND = 6;
+
+    private static int N_PARTITIONS = 16;
+
+    private final int nIntervals;
+
+    private final String orchHost;
+
+    private final int orchPort;
+
+    protected final long dataInterval;
+
+    protected final int nQueryRuns;
+
+    protected final Random randGen;
+
+    public AbstractExperiment7Builder(String name, LSMExperimentSetRunnerConfig config, String clusterConfigFileName,
+            String ingestFileName, String dgenFileName) {
+        super(name, config, clusterConfigFileName, ingestFileName, dgenFileName, null);
+        nIntervals = config.getNIntervals();
+        orchHost = config.getOrchestratorHost();
+        orchPort = config.getOrchestratorPort();
+        dataInterval = config.getDataInterval();
+        this.nQueryRuns = config.getNQueryRuns();
+        this.randGen = new Random();
+    }
+
+    @Override
+    protected void doBuildDataGen(SequentialActionList seq, Map<String, List<String>> dgenPairs) throws Exception {
+        int nDgens = 0;
+        for (List<String> v : dgenPairs.values()) {
+            nDgens += v.size();
+        }
+        final OrchestratorServer7 oServer = new OrchestratorServer7(orchPort, nDgens, nIntervals,
+                new ProtocolActionBuilder(), this.lsAction);
+
+        seq.add(new AbstractAction() {
+
+            @Override
+            protected void doPerform() throws Exception {
+                oServer.start();
+            }
+        });
+
+        ParallelActionSet dgenActions = new ParallelActionSet();
+        int partition = 0;
+
+        // run dgen
+        for (String dgenHost : dgenPairs.keySet()) {
+            final List<String> rcvrs = dgenPairs.get(dgenHost);
+            final int p = partition;
+            dgenActions.add(new AbstractRemoteExecutableAction(dgenHost, username, sshKeyLocation) {
+
+                @Override
+                protected String getCommand() {
+                    String ipPortPairs = StringUtils.join(rcvrs.iterator(), " ");
+                    String binary = "JAVA_HOME=" + javaHomePath + " "
+                            + localExperimentRoot.resolve("bin").resolve("datagenrunner").toString();
+                    return StringUtils.join(new String[] { binary, "-si", "" + locationSampleInterval, "-of",
+                            openStreetMapFilePath, "-p", "" + p, "-di", "" + dataInterval, "-ni", "" + nIntervals,
+                            "-oh", orchHost, "-op", "" + orchPort, ipPortPairs }, " ");
+                }
+            });
+            partition += rcvrs.size();
+        }
+        seq.add(dgenActions);
+
+        // wait until all dgen / queries are done
+        seq.add(new AbstractAction() {
+
+            @Override
+            protected void doPerform() throws Exception {
+                oServer.awaitFinished();
+            }
+        });
+    }
+
+    public class ProtocolActionBuilder implements IProtocolActionBuilder {
+
+        private final String rangeQueryTemplate;
+
+        public ProtocolActionBuilder() {
+            this.rangeQueryTemplate = getRangeQueryTemplate();
+        }
+
+        private String getRangeQueryTemplate() {
+            try {
+                Path aqlTemplateFilePath = localExperimentRoot.resolve(LSMExperimentConstants.AQL_DIR).resolve(
+                        "8_q2.aql");
+                return StandardCharsets.UTF_8.decode(ByteBuffer.wrap(Files.readAllBytes(aqlTemplateFilePath)))
+                        .toString();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        @Override
+        public IAction buildQueryAction(long cardinality, boolean finalRound) throws Exception {
+            SequentialActionList protoAction = new SequentialActionList();
+            IAction rangeQueryAction = new TimedAction(new RunAQLStringAction(httpClient, restHost, restPort,
+                    getRangeAQL(cardinality, finalRound)));
+            protoAction.add(rangeQueryAction);
+            return protoAction;
+        }
+
+        private String getRangeAQL(long cardinaliry, boolean finalRound) throws Exception {
+            long round = QUERY_BEGIN_ROUND;
+            if (finalRound) {
+                ++round;
+            }
+            long numKeys = ((round * dataInterval) / 1000) * N_PARTITIONS;
+            long rangeSize = (long) ((cardinaliry / (double) numKeys) * DOMAIN_SIZE);
+            int lowKey = randGen.nextInt();
+            long maxLowKey = Integer.MAX_VALUE - rangeSize;
+            if (lowKey > maxLowKey) {
+                lowKey = (int) maxLowKey;
+            }
+            int highKey = (int) (lowKey + rangeSize);
+            return rangeQueryTemplate.replaceAll("\\$LKEY\\$", Long.toString(lowKey)).replaceAll("\\$HKEY\\$",
+                    Long.toString(highKey));
+        }
+
+        @Override
+        public IAction buildIOWaitAction() throws Exception {
+            SequentialActionList ioAction = new SequentialActionList();
+            ioAction.add(new SleepAction(10000));
+            ioAction.add(new RunRESTIOWaitAction(httpClient, restHost, restPort));
+            ioAction.add(new SleepAction(10000));
+            return ioAction;
+        }
+
+        @Override
+        public IAction buildCompactAction() throws Exception {
+            return (new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                    LSMExperimentConstants.AQL_DIR).resolve("8_compact.aql")));
+        }
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment8Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment8Builder.java
new file mode 100644
index 0000000..eaafae2
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment8Builder.java
@@ -0,0 +1,189 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import org.apache.commons.lang3.StringUtils;
+
+import org.apache.asterix.experiment.action.base.AbstractAction;
+import org.apache.asterix.experiment.action.base.ParallelActionSet;
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.AbstractRemoteExecutableAction;
+import org.apache.asterix.experiment.action.derived.RunAQLStringAction;
+import org.apache.asterix.experiment.action.derived.RunRESTIOWaitAction;
+import org.apache.asterix.experiment.action.derived.SleepAction;
+import org.apache.asterix.experiment.action.derived.TimedAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+import org.apache.asterix.experiment.client.OrchestratorServer;
+
+public abstract class AbstractExperiment8Builder extends AbstractLSMBaseExperimentBuilder {
+
+    private static final long DOMAIN_SIZE = (1L << 32);
+
+    private static final long EXPECTED_RANGE_CARDINALITY = 50000;
+
+    private static int N_PARTITIONS = 16;
+
+    private final int nIntervals;
+
+    private final String orchHost;
+
+    private final int orchPort;
+
+    protected final long dataInterval;
+
+    protected final int nQueryRuns;
+
+    protected final Random randGen;
+
+    private final String pointQueryTemplate;
+    private final String rangeQueryTemplate;
+
+    public AbstractExperiment8Builder(String name, LSMExperimentSetRunnerConfig config, String clusterConfigFileName,
+            String ingestFileName, String dgenFileName) {
+        super(name, config, clusterConfigFileName, ingestFileName, dgenFileName, null);
+        nIntervals = config.getNIntervals();
+        orchHost = config.getOrchestratorHost();
+        orchPort = config.getOrchestratorPort();
+        dataInterval = config.getDataInterval();
+        this.nQueryRuns = config.getNQueryRuns();
+        this.randGen = new Random();
+        this.pointQueryTemplate = getPointQueryTemplate();
+        this.rangeQueryTemplate = getRangeQueryTemplate();
+    }
+
+    protected void doBuildProtocolAction(SequentialActionList seq, int round) throws Exception {
+        for (int i = 0; i < nQueryRuns; ++i) {
+            //            String aql = getPointLookUpAQL(round);
+            //            seq.add(new TimedAction(new RunAQLStringAction(httpClient, restHost, restPort, aql)));
+            String aql = getRangeAQL(round);
+            seq.add(new TimedAction(new RunAQLStringAction(httpClient, restHost, restPort, aql)));
+        }
+    }
+
+    @Override
+    protected void doBuildDataGen(SequentialActionList seq, Map<String, List<String>> dgenPairs) throws Exception {
+        //start datagen
+        SequentialActionList[] protocolActions = new SequentialActionList[nIntervals];
+        for (int i = 0; i < nIntervals; i++) {
+            protocolActions[i] = new SequentialActionList();
+            protocolActions[i].add(new SleepAction(10000));
+            protocolActions[i].add(new RunRESTIOWaitAction(httpClient, restHost, restPort));
+            protocolActions[i].add(new SleepAction(10000));
+            doBuildProtocolAction(protocolActions[i], i);
+        }
+
+        int nDgens = 0;
+        for (List<String> v : dgenPairs.values()) {
+            nDgens += v.size();
+        }
+        final OrchestratorServer oServer = new OrchestratorServer(orchPort, nDgens, nIntervals, protocolActions);
+
+        seq.add(new AbstractAction() {
+
+            @Override
+            protected void doPerform() throws Exception {
+                oServer.start();
+            }
+        });
+
+        ParallelActionSet dgenActions = new ParallelActionSet();
+        int partition = 0;
+
+        // run dgen
+        for (String dgenHost : dgenPairs.keySet()) {
+            final List<String> rcvrs = dgenPairs.get(dgenHost);
+            final int p = partition;
+            dgenActions.add(new AbstractRemoteExecutableAction(dgenHost, username, sshKeyLocation) {
+
+                @Override
+                protected String getCommand() {
+                    String ipPortPairs = StringUtils.join(rcvrs.iterator(), " ");
+                    String binary = "JAVA_HOME=" + javaHomePath + " "
+                            + localExperimentRoot.resolve("bin").resolve("datagenrunner").toString();
+                    return StringUtils.join(new String[] { binary, "-si", "" + locationSampleInterval, "-of",
+                            openStreetMapFilePath, "-p", "" + p, "-di", "" + dataInterval, "-ni", "" + nIntervals,
+                            "-oh", orchHost, "-op", "" + orchPort, ipPortPairs }, " ");
+                }
+            });
+            partition += rcvrs.size();
+        }
+        seq.add(dgenActions);
+
+        // wait until all dgen / queries are done
+        seq.add(new AbstractAction() {
+
+            @Override
+            protected void doPerform() throws Exception {
+                oServer.awaitFinished();
+            }
+        });
+    }
+
+    private String getRangeQueryTemplate() {
+        try {
+            Path aqlTemplateFilePath = localExperimentRoot.resolve(LSMExperimentConstants.AQL_DIR).resolve("8_q2.aql");
+            return StandardCharsets.UTF_8.decode(ByteBuffer.wrap(Files.readAllBytes(aqlTemplateFilePath))).toString();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private String getPointQueryTemplate() {
+        try {
+            Path aqlTemplateFilePath = localExperimentRoot.resolve(LSMExperimentConstants.AQL_DIR).resolve("8_q1.aql");
+            return StandardCharsets.UTF_8.decode(ByteBuffer.wrap(Files.readAllBytes(aqlTemplateFilePath))).toString();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    protected String getPointLookUpAQL(int round) throws Exception {
+        ByteBuffer bb = ByteBuffer.allocate(8);
+        bb.put((byte) 0);
+        bb.put((byte) randGen.nextInt(N_PARTITIONS));
+        bb.putShort((short) 0);
+        bb.putInt(randGen.nextInt((int) (((1 + round) * dataInterval) / 1000)));
+        bb.flip();
+        long key = bb.getLong();
+        return pointQueryTemplate.replaceAll("\\$KEY\\$", Long.toString(key));
+    }
+
+    protected String getRangeAQL(int round) throws Exception {
+        long numKeys = (((1 + round) * dataInterval) / 1000) * N_PARTITIONS;
+        long rangeSize = (long) ((EXPECTED_RANGE_CARDINALITY / (double) numKeys) * DOMAIN_SIZE);
+        int lowKey = randGen.nextInt();
+        long maxLowKey = Integer.MAX_VALUE - rangeSize;
+        if (lowKey > maxLowKey) {
+            lowKey = (int) maxLowKey;
+        }
+        int highKey = (int) (lowKey + rangeSize);
+        return rangeQueryTemplate.replaceAll("\\$LKEY\\$", Long.toString(lowKey)).replaceAll("\\$HKEY\\$",
+                Long.toString(highKey));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment9Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment9Builder.java
new file mode 100644
index 0000000..6d36f1d
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperiment9Builder.java
@@ -0,0 +1,196 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import org.apache.commons.lang3.StringUtils;
+
+import org.apache.asterix.experiment.action.base.AbstractAction;
+import org.apache.asterix.experiment.action.base.IAction;
+import org.apache.asterix.experiment.action.base.ParallelActionSet;
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.AbstractRemoteExecutableAction;
+import org.apache.asterix.experiment.action.derived.RunAQLStringAction;
+import org.apache.asterix.experiment.action.derived.TimedAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+import org.apache.asterix.experiment.client.OrchestratorServer9;
+import org.apache.asterix.experiment.client.OrchestratorServer9.IProtocolActionBuilder;
+
+public abstract class AbstractExperiment9Builder extends AbstractLSMBaseExperimentBuilder {
+
+    private static final long DOMAIN_SIZE = (1L << 32);
+
+    private static final long EXPECTED_RANGE_CARDINALITY = 1000;
+
+    private static int N_PARTITIONS = 16;
+
+    private final int nIntervals;
+
+    private final String orchHost;
+
+    private final int orchPort;
+
+    protected final long dataInterval;
+
+    protected final int nQueryRuns;
+
+    protected final Random randGen;
+
+    public AbstractExperiment9Builder(String name, LSMExperimentSetRunnerConfig config, String clusterConfigFileName,
+            String ingestFileName, String dgenFileName) {
+        super(name, config, clusterConfigFileName, ingestFileName, dgenFileName, null);
+        nIntervals = config.getNIntervals();
+        orchHost = config.getOrchestratorHost();
+        orchPort = config.getOrchestratorPort();
+        dataInterval = config.getDataInterval();
+        this.nQueryRuns = config.getNQueryRuns();
+        this.randGen = new Random();
+    }
+
+    @Override
+    protected void doBuildDataGen(SequentialActionList seq, Map<String, List<String>> dgenPairs) throws Exception {
+        int nDgens = 0;
+        for (List<String> v : dgenPairs.values()) {
+            nDgens += v.size();
+        }
+        final OrchestratorServer9 oServer = new OrchestratorServer9(orchPort, nDgens, nIntervals,
+                new ProtocolActionBuilder());
+
+        seq.add(new AbstractAction() {
+
+            @Override
+            protected void doPerform() throws Exception {
+                oServer.start();
+            }
+        });
+
+        ParallelActionSet dgenActions = new ParallelActionSet();
+        int partition = 0;
+
+        // run dgen
+        for (String dgenHost : dgenPairs.keySet()) {
+            final List<String> rcvrs = dgenPairs.get(dgenHost);
+            final int p = partition;
+            dgenActions.add(new AbstractRemoteExecutableAction(dgenHost, username, sshKeyLocation) {
+
+                @Override
+                protected String getCommand() {
+                    String ipPortPairs = StringUtils.join(rcvrs.iterator(), " ");
+                    String binary = "JAVA_HOME=" + javaHomePath + " "
+                            + localExperimentRoot.resolve("bin").resolve("datagenrunner").toString();
+                    return StringUtils.join(new String[] { binary, "-si", "" + locationSampleInterval, "-of",
+                            openStreetMapFilePath, "-p", "" + p, "-di", "" + dataInterval, "-ni", "" + nIntervals,
+                            "-oh", orchHost, "-op", "" + orchPort, ipPortPairs }, " ");
+                }
+            });
+            partition += rcvrs.size();
+        }
+        seq.add(dgenActions);
+
+        // wait until all dgen / queries are done
+        seq.add(new AbstractAction() {
+
+            @Override
+            protected void doPerform() throws Exception {
+                oServer.awaitFinished();
+            }
+        });
+    }
+
+    public class ProtocolActionBuilder implements IProtocolActionBuilder {
+
+        private final String pointQueryTemplate;
+
+        private final String rangeQueryTemplate;
+
+        public ProtocolActionBuilder() {
+            this.pointQueryTemplate = getPointQueryTemplate();
+            this.rangeQueryTemplate = getRangeQueryTemplate();
+        }
+
+        private String getRangeQueryTemplate() {
+            try {
+                Path aqlTemplateFilePath = localExperimentRoot.resolve(LSMExperimentConstants.AQL_DIR).resolve(
+                        "8_q2.aql");
+                return StandardCharsets.UTF_8.decode(ByteBuffer.wrap(Files.readAllBytes(aqlTemplateFilePath)))
+                        .toString();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        private String getPointQueryTemplate() {
+            try {
+                Path aqlTemplateFilePath = localExperimentRoot.resolve(LSMExperimentConstants.AQL_DIR).resolve(
+                        "8_q1.aql");
+                return StandardCharsets.UTF_8.decode(ByteBuffer.wrap(Files.readAllBytes(aqlTemplateFilePath)))
+                        .toString();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        @Override
+        public IAction buildAction(int round) throws Exception {
+            SequentialActionList protoAction = new SequentialActionList();
+            IAction pointQueryAction = new TimedAction(new RunAQLStringAction(httpClient, restHost, restPort,
+                    getPointLookUpAQL(round)));
+            IAction rangeQueryAction = new TimedAction(new RunAQLStringAction(httpClient, restHost, restPort,
+                    getRangeAQL(round)));
+            protoAction.add(pointQueryAction);
+            protoAction.add(rangeQueryAction);
+            return protoAction;
+        }
+
+        private String getPointLookUpAQL(int round) throws Exception {
+            ByteBuffer bb = ByteBuffer.allocate(8);
+            bb.put((byte) 0);
+            bb.put((byte) randGen.nextInt(N_PARTITIONS));
+            bb.putShort((short) 0);
+            bb.putInt(randGen.nextInt((int) (((1 + round) * dataInterval) / 1000)));
+            bb.flip();
+            long key = bb.getLong();
+            return pointQueryTemplate.replaceAll("\\$KEY\\$", Long.toString(key));
+        }
+
+        private String getRangeAQL(int round) throws Exception {
+            long numKeys = (((1 + round) * dataInterval) / 1000) * N_PARTITIONS;
+            long rangeSize = (long) ((EXPECTED_RANGE_CARDINALITY / (double) numKeys) * DOMAIN_SIZE);
+            int lowKey = randGen.nextInt();
+            long maxLowKey = Integer.MAX_VALUE - rangeSize;
+            if (lowKey > maxLowKey) {
+                lowKey = (int) maxLowKey;
+            }
+            int highKey = (int) (lowKey + rangeSize);
+            return rangeQueryTemplate.replaceAll("\\$LKEY\\$", Long.toString(lowKey)).replaceAll("\\$HKEY\\$",
+                    Long.toString(highKey));
+        }
+
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperimentBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperimentBuilder.java
new file mode 100644
index 0000000..1717652
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractExperimentBuilder.java
@@ -0,0 +1,40 @@
+/*
+ * 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.asterix.experiment.builder;
+
+public abstract class AbstractExperimentBuilder {
+    private final String name;
+
+    protected AbstractExperimentBuilder(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public final Experiment build() throws Exception {
+        Experiment e = new Experiment(name);
+        doBuild(e);
+        return e;
+    }
+
+    protected abstract void doBuild(Experiment e) throws Exception;
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractLSMBaseExperimentBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractLSMBaseExperimentBuilder.java
new file mode 100644
index 0000000..1a57480
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractLSMBaseExperimentBuilder.java
@@ -0,0 +1,357 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.Set;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.asterix.event.schema.cluster.Cluster;
+import org.apache.asterix.experiment.action.base.ParallelActionSet;
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.AbstractRemoteExecutableAction;
+import org.apache.asterix.experiment.action.derived.ManagixActions.CreateAsterixManagixAction;
+import org.apache.asterix.experiment.action.derived.ManagixActions.DeleteAsterixManagixAction;
+import org.apache.asterix.experiment.action.derived.ManagixActions.LogAsterixManagixAction;
+import org.apache.asterix.experiment.action.derived.ManagixActions.StopAsterixManagixAction;
+import org.apache.asterix.experiment.action.derived.RemoteAsterixDriverKill;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.action.derived.SleepAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.DefaultHttpClient;
+
+public abstract class AbstractLSMBaseExperimentBuilder extends AbstractExperimentBuilder {
+
+    private static final String ASTERIX_INSTANCE_NAME = "a1";
+
+    private final String logDirSuffix;
+
+    protected final HttpClient httpClient;
+
+    protected final String restHost;
+
+    protected final int restPort;
+
+    private final String managixHomePath;
+
+    protected final String javaHomePath;
+
+    protected final Path localExperimentRoot;
+
+    protected final String username;
+
+    protected final String sshKeyLocation;
+
+    private final int duration;
+
+    private final String clusterConfigFileName;
+
+    private final String ingestFileName;
+
+    protected final String dgenFileName;
+
+    private final String countFileName;
+
+    private final String statFile;
+
+    protected final SequentialActionList lsAction;
+
+    protected final String openStreetMapFilePath;
+    protected final int locationSampleInterval;
+
+    protected final int recordCountPerBatchDuringIngestionOnly;
+    protected final int recordCountPerBatchDuringQuery;
+    protected final long dataGenSleepTimeDuringIngestionOnly;
+    protected final long dataGenSleepTimeDuringQuery;
+
+    public AbstractLSMBaseExperimentBuilder(String name, LSMExperimentSetRunnerConfig config,
+            String clusterConfigFileName, String ingestFileName, String dgenFileName, String countFileName) {
+        super(name);
+        this.logDirSuffix = config.getLogDirSuffix();
+        this.httpClient = new DefaultHttpClient();
+        this.restHost = config.getRESTHost();
+        this.restPort = config.getRESTPort();
+        this.managixHomePath = config.getManagixHome();
+        this.javaHomePath = config.getJavaHome();
+        this.localExperimentRoot = Paths.get(config.getLocalExperimentRoot());
+        this.username = config.getUsername();
+        this.sshKeyLocation = config.getSSHKeyLocation();
+        this.duration = config.getDuration();
+        this.clusterConfigFileName = clusterConfigFileName;
+        this.ingestFileName = ingestFileName;
+        this.dgenFileName = dgenFileName;
+        this.countFileName = countFileName;
+        this.statFile = config.getStatFile();
+        this.lsAction = new SequentialActionList();
+        this.openStreetMapFilePath = config.getOpenStreetMapFilePath();
+        this.locationSampleInterval = config.getLocationSampleInterval();
+        recordCountPerBatchDuringIngestionOnly = config.getRecordCountPerBatchDuringIngestionOnly();
+        recordCountPerBatchDuringQuery = config.getRecordCountPerBatchDuringQuery();
+        dataGenSleepTimeDuringIngestionOnly = config.getDataGenSleepTimeDuringIngestionOnly();
+        dataGenSleepTimeDuringQuery = config.getDataGenSleepTimeDuringQuery();
+    }
+
+    protected abstract void doBuildDDL(SequentialActionList seq);
+
+    protected void doPost(SequentialActionList seq) {
+    }
+
+    protected void doBuildDataGen(SequentialActionList seq, final Map<String, List<String>> dgenPairs) throws Exception {
+
+        //start datagen
+        ParallelActionSet dgenActions = new ParallelActionSet();
+        int partition = 0;
+        for (String dgenHost : dgenPairs.keySet()) {
+            final List<String> rcvrs = dgenPairs.get(dgenHost);
+            final int p = partition;
+            dgenActions.add(new AbstractRemoteExecutableAction(dgenHost, username, sshKeyLocation) {
+
+                @Override
+                protected String getCommand() {
+                    String ipPortPairs = StringUtils.join(rcvrs.iterator(), " ");
+                    String binary = "JAVA_HOME=" + javaHomePath + " "
+                            + localExperimentRoot.resolve("bin").resolve("datagenrunner").toString();
+                    if (openStreetMapFilePath == null) {
+                        return StringUtils.join(new String[] { binary, "-rcbi",
+                                "" + recordCountPerBatchDuringIngestionOnly, "-rcbq",
+                                "" + recordCountPerBatchDuringQuery, "-dsti", "" + dataGenSleepTimeDuringIngestionOnly,
+                                "-dstq", "" + dataGenSleepTimeDuringQuery, "-si", "" + locationSampleInterval, "-p",
+                                "" + p, "-d", "" + duration, ipPortPairs }, " ");
+                    } else {
+                        return StringUtils.join(new String[] { binary, "-rcbi",
+                                "" + recordCountPerBatchDuringIngestionOnly, "-rcbq",
+                                "" + recordCountPerBatchDuringQuery, "-dsti", "" + dataGenSleepTimeDuringIngestionOnly,
+                                "-dstq", "" + dataGenSleepTimeDuringQuery, "-si", "" + locationSampleInterval, "-of",
+                                openStreetMapFilePath, "-p", "" + p, "-d", "" + duration, ipPortPairs }, " ");
+                    }
+                }
+            });
+            partition += rcvrs.size();
+        }
+        seq.add(dgenActions);
+    }
+
+    @Override
+    protected void doBuild(Experiment e) throws Exception {
+        SequentialActionList execs = new SequentialActionList();
+
+        String clusterConfigPath = localExperimentRoot.resolve(LSMExperimentConstants.CONFIG_DIR)
+                .resolve(clusterConfigFileName).toString();
+        String asterixConfigPath = localExperimentRoot.resolve(LSMExperimentConstants.CONFIG_DIR)
+                .resolve(LSMExperimentConstants.ASTERIX_CONFIGURATION).toString();
+
+        //create instance
+        execs.add(new StopAsterixManagixAction(managixHomePath, ASTERIX_INSTANCE_NAME));
+        execs.add(new DeleteAsterixManagixAction(managixHomePath, ASTERIX_INSTANCE_NAME));
+        execs.add(new SleepAction(30000));
+        execs.add(new CreateAsterixManagixAction(managixHomePath, ASTERIX_INSTANCE_NAME, clusterConfigPath,
+                asterixConfigPath));
+
+        //run ddl statements
+        execs.add(new SleepAction(15000));
+        // TODO: implement retry handler
+        execs.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve(LSMExperimentConstants.BASE_TYPES)));
+        doBuildDDL(execs);
+        execs.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot
+                .resolve(LSMExperimentConstants.AQL_DIR).resolve(LSMExperimentConstants.BASE_DIR)
+                .resolve(ingestFileName)));
+
+        Map<String, List<String>> dgenPairs = readDatagenPairs(localExperimentRoot.resolve(
+                LSMExperimentConstants.DGEN_DIR).resolve(dgenFileName));
+        final Set<String> ncHosts = new HashSet<>();
+        for (List<String> ncHostList : dgenPairs.values()) {
+            for (String ncHost : ncHostList) {
+                ncHosts.add(ncHost.split(":")[0]);
+            }
+        }
+
+        if (statFile != null) {
+            ParallelActionSet ioCountActions = new ParallelActionSet();
+            for (String ncHost : ncHosts) {
+                ioCountActions.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+
+                    @Override
+                    protected String getCommand() {
+                        String cmd = "screen -d -m sh -c \"sar -b -u 1 > " + statFile + "\"";
+                        return cmd;
+                    }
+                });
+            }
+            execs.add(ioCountActions);
+        }
+
+        SequentialActionList postLSAction = new SequentialActionList();
+        File file = new File(clusterConfigPath);
+        JAXBContext ctx = JAXBContext.newInstance(Cluster.class);
+        Unmarshaller unmarshaller = ctx.createUnmarshaller();
+        final Cluster cluster = (Cluster) unmarshaller.unmarshal(file);
+        String[] storageRoots = cluster.getIodevices().split(",");
+        for (String ncHost : ncHosts) {
+            for (final String sRoot : storageRoots) {
+                lsAction.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+                    @Override
+                    protected String getCommand() {
+                        return "ls -Rl " + sRoot;
+                    }
+                });
+                postLSAction.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+                    @Override
+                    protected String getCommand() {
+                        return "ls -Rl " + sRoot;
+                    }
+                });
+
+            }
+        }
+
+        // main exp
+        doBuildDataGen(execs, dgenPairs);
+
+        //        if (statFile != null) {
+        //            ParallelActionSet ioCountKillActions = new ParallelActionSet();
+        //            for (String ncHost : ncHosts) {
+        //                ioCountKillActions.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+        //
+        //                    @Override
+        //                    protected String getCommand() {
+        //                        String cmd = "screen -X -S `screen -list | grep Detached | awk '{print $1}'` quit";
+        //                        return cmd;
+        //                    }
+        //                });
+        //            }
+        //            execs.add(ioCountKillActions);
+        //        }
+
+        execs.add(new SleepAction(10000));
+        if (countFileName != null) {
+            execs.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                    LSMExperimentConstants.AQL_DIR).resolve(countFileName)));
+        }
+
+        execs.add(postLSAction);
+        doPost(execs);
+        ParallelActionSet killCmds = new ParallelActionSet();
+        for (String ncHost : ncHosts) {
+            killCmds.add(new RemoteAsterixDriverKill(ncHost, username, sshKeyLocation));
+        }
+        //killCmds.add(new RemoteAsterixDriverKill(restHost, username, sshKeyLocation));
+        execs.add(killCmds);
+        execs.add(new StopAsterixManagixAction(managixHomePath, ASTERIX_INSTANCE_NAME));
+        if (statFile != null) {
+            ParallelActionSet collectIOActions = new ParallelActionSet();
+            for (String ncHost : ncHosts) {
+                collectIOActions.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+
+                    @Override
+                    protected String getCommand() {
+                        String cmd = "cp " + statFile + " " + cluster.getLogDir();
+                        return cmd;
+                    }
+                });
+            }
+            execs.add(collectIOActions);
+        }
+
+        //collect profile information
+        //        if (ExperimentProfiler.PROFILE_MODE) {
+        //            if (!SpatialIndexProfiler.PROFILE_HOME_DIR.contentEquals(cluster.getLogDir())) {
+        //                ParallelActionSet collectProfileInfo = new ParallelActionSet();
+        //                for (String ncHost : ncHosts) {
+        //                    collectProfileInfo.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+        //                        @Override
+        //                        protected String getCommand() {
+        //                            String cmd = "mv " + SpatialIndexProfiler.PROFILE_HOME_DIR + "*.txt " + cluster.getLogDir();
+        //                            return cmd;
+        //                        }
+        //                    });
+        //                }
+        //                execs.add(collectProfileInfo);
+        //            }
+        //        }
+
+        execs.add(new LogAsterixManagixAction(managixHomePath, ASTERIX_INSTANCE_NAME, localExperimentRoot
+                .resolve(LSMExperimentConstants.LOG_DIR + "-" + logDirSuffix).resolve(getName()).toString()));
+
+        if (getName().contains("SpatialIndexExperiment2") || getName().contains("SpatialIndexExperiment5")) {
+            //get query result file
+            SequentialActionList getQueryResultFileActions = new SequentialActionList();
+            final String queryResultFilePath = openStreetMapFilePath.substring(0,
+                    openStreetMapFilePath.lastIndexOf(File.separator))
+                    + File.separator + "QueryGenResult-*.txt";
+            for (final String qgenHost : dgenPairs.keySet()) {
+                getQueryResultFileActions.add(new AbstractRemoteExecutableAction(restHost, username, sshKeyLocation) {
+
+                    @Override
+                    protected String getCommand() {
+                        String cmd = "scp "
+                                + username
+                                + "@"
+                                + qgenHost
+                                + ":"
+                                + queryResultFilePath
+                                + " "
+                                + localExperimentRoot.resolve(LSMExperimentConstants.LOG_DIR + "-" + logDirSuffix)
+                                        .resolve(getName()).toString();
+                        return cmd;
+                    }
+                });
+            }
+            execs.add(getQueryResultFileActions);
+        }
+
+        e.addBody(execs);
+    }
+
+    protected Map<String, List<String>> readDatagenPairs(Path p) throws IOException {
+        Map<String, List<String>> dgenPairs = new HashMap<>();
+        Scanner s = new Scanner(p, StandardCharsets.UTF_8.name());
+        try {
+            while (s.hasNextLine()) {
+                String line = s.nextLine();
+                String[] pair = line.split("\\s+");
+                List<String> vals = dgenPairs.get(pair[0]);
+                if (vals == null) {
+                    vals = new ArrayList<>();
+                    dgenPairs.put(pair[0], vals);
+                }
+                vals.add(pair[1]);
+            }
+        } finally {
+            s.close();
+        }
+        return dgenPairs;
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractLocalExperimentBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractLocalExperimentBuilder.java
new file mode 100644
index 0000000..eac4ac2
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractLocalExperimentBuilder.java
@@ -0,0 +1,119 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.hyracks.bootstrap.CCApplicationEntryPoint;
+import org.apache.asterix.hyracks.bootstrap.NCApplicationEntryPoint;
+import org.apache.hyracks.control.cc.ClusterControllerService;
+import org.apache.hyracks.control.common.controllers.CCConfig;
+import org.apache.hyracks.control.common.controllers.NCConfig;
+import org.apache.hyracks.control.nc.NodeControllerService;
+
+public abstract class AbstractLocalExperimentBuilder extends AbstractExperimentBuilder {
+
+    private final int nNodeControllers;
+
+    protected AbstractLocalExperimentBuilder(String name, int nNodeControllers) {
+        super(name);
+        this.nNodeControllers = nNodeControllers;
+    }
+
+    protected abstract void addPre(SequentialActionList pre);
+
+    protected abstract void addPost(SequentialActionList post);
+
+//    @Override
+//    protected void prePost(SequentialExecutableSet pre, SequentialExecutableSet post) {
+//        int ccClientPort = 1098;
+//        int ccClusterPort = 1099;
+//        CCConfig ccConfig = new CCConfig();
+//        ccConfig.clusterNetIpAddress = "127.0.0.1";
+//        ccConfig.clientNetIpAddress = "127.0.0.1";
+//        ccConfig.clientNetPort = ccClientPort;
+//        ccConfig.clusterNetPort = ccClusterPort;
+//        ccConfig.defaultMaxJobAttempts = 0;
+//        ccConfig.resultTTL = 30000;
+//        ccConfig.resultSweepThreshold = 1000;
+//        ccConfig.appCCMainClass = CCApplicationEntryPoint.class.getName();
+//        final ClusterControllerService cc;
+//        try {
+//            cc = new ClusterControllerService(ccConfig);
+//        } catch (Exception e) {
+//            throw new IllegalArgumentException(e);
+//        }
+//
+//        final List<NodeControllerService> ncs = new ArrayList<>();
+//        for (int i = 0; i < nNodeControllers; ++i) {
+//            NCConfig ncConfig = new NCConfig();
+//            ncConfig.ccHost = "localhost";
+//            ncConfig.ccPort = ccClusterPort;
+//            ncConfig.clusterNetIPAddress = "127.0.0.1";
+//            ncConfig.dataIPAddress = "127.0.0.1";
+//            ncConfig.datasetIPAddress = "127.0.0.1";
+//            ncConfig.nodeId = "nc" + String.valueOf((i + 1));
+//            ncConfig.resultTTL = 30000;
+//            ncConfig.resultSweepThreshold = 1000;
+//            Path p0 = Paths.get(System.getProperty("java.io.tmpdir"), ncConfig.nodeId, "iodevice0");
+//            Path p1 = Paths.get(System.getProperty("java.io.tmpdir"), ncConfig.nodeId, "iodevice1");
+//            ncConfig.ioDevices = p0.toString() + "," + p1.toString();
+//            ncConfig.appNCMainClass = NCApplicationEntryPoint.class.getName();
+//            NodeControllerService nc;
+//            try {
+//                nc = new NodeControllerService(ncConfig);
+//            } catch (Exception e) {
+//                throw new IllegalArgumentException(e);
+//            }
+//            ncs.add(nc);
+//        }
+//
+//        pre.add(new AbstractExecutable() {
+//
+//            @Override
+//            protected void doExecute() throws Exception {
+//                cc.start();
+//                for (NodeControllerService nc : ncs) {
+//                    nc.start();
+//                }
+//            }
+//        });
+//
+//        post.add(new AbstractExecutable() {
+//
+//            @Override
+//            protected void doExecute() throws Exception {
+//                Collections.reverse(ncs);
+//                for (NodeControllerService nc : ncs) {
+//                    nc.stop();
+//                }
+//                cc.stop();
+//                System.exit(1);
+//            }
+//        });
+//        addPre(pre);
+//        addPost(post);
+//    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractSpatialIndexExperiment2Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractSpatialIndexExperiment2Builder.java
new file mode 100644
index 0000000..848ab7c
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractSpatialIndexExperiment2Builder.java
@@ -0,0 +1,173 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import org.apache.asterix.experiment.action.base.AbstractAction;
+import org.apache.asterix.experiment.action.base.ParallelActionSet;
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.AbstractRemoteExecutableAction;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+import org.apache.asterix.experiment.client.SpatialIndexExperiment2OrchestratorServer;
+import org.apache.commons.lang3.StringUtils;
+
+public abstract class AbstractSpatialIndexExperiment2Builder extends AbstractLSMBaseExperimentBuilder {
+
+    private static final long DOMAIN_SIZE = (1L << 32);
+
+    public static final long QUERY_BEGIN_ROUND = 6;
+
+    private static int N_PARTITIONS = 16;
+
+    private final int nIntervals;
+
+    private final String dataGenOrchHost;
+
+    private final int dataGenOrchPort;
+
+    private final String queryGenOrchHost;
+
+    private final int queryGenOrchPort;
+
+    private final long queryGenDuration;
+
+    protected final long dataInterval;
+
+    protected final int nQueryRuns;
+
+    protected final Random randGen;
+
+    protected final boolean isIndexOnlyPlan;
+
+    public AbstractSpatialIndexExperiment2Builder(String name, LSMExperimentSetRunnerConfig config,
+            String clusterConfigFileName, String ingestFileName, String dgenFileName, boolean isIndexOnlyPlan) {
+        super(name, config, clusterConfigFileName, ingestFileName, dgenFileName, null);
+        nIntervals = config.getNIntervals();
+        dataGenOrchHost = config.getOrchestratorHost();
+        dataGenOrchPort = config.getOrchestratorPort();
+        dataInterval = config.getDataInterval();
+        queryGenOrchHost = config.getQueryOrchestratorHost();
+        queryGenOrchPort = config.getQueryOrchestratorPort();
+        queryGenDuration = config.getQueryDuration();
+        this.nQueryRuns = config.getNQueryRuns();
+        this.randGen = new Random();
+        this.isIndexOnlyPlan = isIndexOnlyPlan;
+    }
+
+    @Override
+    protected void doBuildDataGen(SequentialActionList seq, Map<String, List<String>> dgenPairs) throws Exception {
+        int nDgens = 0;
+        for (List<String> v : dgenPairs.values()) {
+            nDgens += v.size();
+        }
+        final SpatialIndexExperiment2OrchestratorServer oServer = new SpatialIndexExperiment2OrchestratorServer(
+                dataGenOrchPort, nDgens, nIntervals, queryGenOrchPort, nDgens /*for now, query gen uses the same node as data gen*/);
+
+        seq.add(new AbstractAction() {
+
+            @Override
+            protected void doPerform() throws Exception {
+                oServer.start();
+            }
+        });
+
+        //prepare data gen runner and query gen runner
+        //note that dgenPairs.keySet() are used as query gen runners' ip address.
+        ParallelActionSet dataAndQueryGenActions = new ParallelActionSet();
+        int partition = 0;
+        for (String dgenHost : dgenPairs.keySet()) {
+            final List<String> rcvrs = dgenPairs.get(dgenHost);
+            final int p = partition;
+            //prepare data gen
+            dataAndQueryGenActions.add(new AbstractRemoteExecutableAction(dgenHost, username, sshKeyLocation) {
+
+                @Override
+                protected String getCommand() {
+                    String ipPortPairs = StringUtils.join(rcvrs.iterator(), " ");
+                    String binary = "JAVA_HOME=" + javaHomePath + " "
+                            + localExperimentRoot.resolve("bin").resolve("datagenrunner").toString();
+                    if (openStreetMapFilePath == null) {
+                        return StringUtils.join(new String[] { binary, "-rcbi",
+                                "" + recordCountPerBatchDuringIngestionOnly, "-rcbq",
+                                "" + recordCountPerBatchDuringQuery, "-dsti", "" + dataGenSleepTimeDuringIngestionOnly,
+                                "-dstq", "" + dataGenSleepTimeDuringQuery, "-si", "" + locationSampleInterval, "-p",
+                                "" + p, "-di", "" + dataInterval, "-ni", "" + nIntervals, "-qd", "" + queryGenDuration,
+                                "-oh", dataGenOrchHost, "-op", "" + dataGenOrchPort, ipPortPairs }, " ");
+                    } else {
+                        return StringUtils.join(new String[] { binary, "-rcbi",
+                                "" + recordCountPerBatchDuringIngestionOnly, "-rcbq",
+                                "" + recordCountPerBatchDuringQuery, "-dsti", "" + dataGenSleepTimeDuringIngestionOnly,
+                                "-dstq", "" + dataGenSleepTimeDuringQuery, "-si", "" + locationSampleInterval, "-of",
+                                openStreetMapFilePath, "-p", "" + p, "-di", "" + dataInterval, "-ni", "" + nIntervals,
+                                "-qd", "" + queryGenDuration, "-oh", dataGenOrchHost, "-op", "" + dataGenOrchPort,
+                                ipPortPairs }, " ");
+                    }
+                }
+            });
+
+            //prepare query gen
+            dataAndQueryGenActions.add(new AbstractRemoteExecutableAction(dgenHost, username, sshKeyLocation) {
+
+                @Override
+                protected String getCommand() {
+                    String ipPortPairs = StringUtils.join(rcvrs.iterator(), " ");
+                    String binary = "JAVA_HOME=" + javaHomePath + " "
+                            + localExperimentRoot.resolve("bin").resolve("querygenrunner").toString();
+                    if (openStreetMapFilePath == null) {
+                        if (isIndexOnlyPlan) {
+                            return StringUtils.join(new String[] { binary, "-iop", "-p", "" + p, "-qd",
+                                    "" + queryGenDuration, "-qoh", "" + queryGenOrchHost, "-qop",
+                                    "" + queryGenOrchPort, "-rh", restHost, "-rp", "" + restPort }, " ");
+                        } else {
+                            return StringUtils.join(new String[] { binary, "-p", "" + p, "-qd", "" + queryGenDuration,
+                                    "-qoh", "" + queryGenOrchHost, "-qop", "" + queryGenOrchPort, "-rh", restHost,
+                                    "-rp", "" + restPort }, " ");
+                        }
+                    } else {
+                        if (isIndexOnlyPlan) {
+                            return StringUtils.join(new String[] { binary, "-iop", "-of", openStreetMapFilePath, "-p",
+                                    "" + p, "-qd", "" + queryGenDuration, "-qoh", "" + queryGenOrchHost, "-qop",
+                                    "" + queryGenOrchPort, "-rh", restHost, "-rp", "" + restPort }, " ");
+                        } else {
+                            return StringUtils.join(new String[] { binary, "-of", openStreetMapFilePath, "-p", "" + p,
+                                    "-qd", "" + queryGenDuration, "-qoh", "" + queryGenOrchHost, "-qop",
+                                    "" + queryGenOrchPort, "-rh", restHost, "-rp", "" + restPort }, " ");
+                        }
+                    }
+                }
+            });
+
+            partition += rcvrs.size();
+        }
+        seq.add(dataAndQueryGenActions);
+
+        // wait until all dgen / queries are done
+        seq.add(new AbstractAction() {
+
+            @Override
+            protected void doPerform() throws Exception {
+                oServer.awaitFinished();
+            }
+        });
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractSpatialIndexExperiment3PIdxLoadBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractSpatialIndexExperiment3PIdxLoadBuilder.java
new file mode 100644
index 0000000..6de1c73
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractSpatialIndexExperiment3PIdxLoadBuilder.java
@@ -0,0 +1,293 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.Set;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.asterix.event.schema.cluster.Cluster;
+import org.apache.asterix.experiment.action.base.ParallelActionSet;
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.AbstractRemoteExecutableAction;
+import org.apache.asterix.experiment.action.derived.ManagixActions.CreateAsterixManagixAction;
+import org.apache.asterix.experiment.action.derived.ManagixActions.DeleteAsterixManagixAction;
+import org.apache.asterix.experiment.action.derived.ManagixActions.LogAsterixManagixAction;
+import org.apache.asterix.experiment.action.derived.ManagixActions.StopAsterixManagixAction;
+import org.apache.asterix.experiment.action.derived.RemoteAsterixDriverKill;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.action.derived.SleepAction;
+import org.apache.asterix.experiment.action.derived.TimedAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.DefaultHttpClient;
+
+/**
+ * This class is used to create experiments for spatial index static data evaluation, that is, no ingestion is involved.
+ * Also, there is no orchestration server involved in this experiment builder.
+ */
+public abstract class AbstractSpatialIndexExperiment3PIdxLoadBuilder extends AbstractExperimentBuilder {
+
+    private static final String ASTERIX_INSTANCE_NAME = "a1";
+
+    private final String logDirSuffix;
+
+    protected final HttpClient httpClient;
+
+    protected final String restHost;
+
+    protected final int restPort;
+
+    private final String managixHomePath;
+
+    protected final String javaHomePath;
+
+    protected final Path localExperimentRoot;
+
+    protected final String username;
+
+    protected final String sshKeyLocation;
+
+    private final int duration;
+
+    private final String clusterConfigFileName;
+
+    private final String ingestFileName;
+
+    protected final String dgenFileName;
+
+    private final String countFileName;
+
+    private final String statFile;
+
+    protected final SequentialActionList lsAction;
+
+    protected final String openStreetMapFilePath;
+
+    protected final int locationSampleInterval;
+
+    protected final String loadAQLFilePath;
+
+    public AbstractSpatialIndexExperiment3PIdxLoadBuilder(String name, LSMExperimentSetRunnerConfig config,
+            String clusterConfigFileName, String ingestFileName, String dgenFileName, String countFileName,
+            String loadAQLFileName) {
+        super(name);
+        this.logDirSuffix = config.getLogDirSuffix();
+        this.httpClient = new DefaultHttpClient();
+        this.restHost = config.getRESTHost();
+        this.restPort = config.getRESTPort();
+        this.managixHomePath = config.getManagixHome();
+        this.javaHomePath = config.getJavaHome();
+        this.localExperimentRoot = Paths.get(config.getLocalExperimentRoot());
+        this.username = config.getUsername();
+        this.sshKeyLocation = config.getSSHKeyLocation();
+        this.duration = config.getDuration();
+        this.clusterConfigFileName = clusterConfigFileName;
+        this.ingestFileName = ingestFileName;
+        this.dgenFileName = dgenFileName;
+        this.countFileName = countFileName;
+        this.statFile = config.getStatFile();
+        this.lsAction = new SequentialActionList();
+        this.openStreetMapFilePath = config.getOpenStreetMapFilePath();
+        this.locationSampleInterval = config.getLocationSampleInterval();
+        this.loadAQLFilePath = loadAQLFileName;
+    }
+
+    protected abstract void doBuildDDL(SequentialActionList seq);
+
+    protected void doPost(SequentialActionList seq) {
+    }
+
+    protected void doBuildDataGen(SequentialActionList seq, final Map<String, List<String>> dgenPairs) throws Exception {
+    }
+
+    @Override
+    protected void doBuild(Experiment e) throws Exception {
+        SequentialActionList execs = new SequentialActionList();
+
+        String clusterConfigPath = localExperimentRoot.resolve(LSMExperimentConstants.CONFIG_DIR)
+                .resolve(clusterConfigFileName).toString();
+        String asterixConfigPath = localExperimentRoot.resolve(LSMExperimentConstants.CONFIG_DIR)
+                .resolve(LSMExperimentConstants.ASTERIX_CONFIGURATION).toString();
+
+        //stop/delete/create instance
+        execs.add(new StopAsterixManagixAction(managixHomePath, ASTERIX_INSTANCE_NAME));
+        execs.add(new DeleteAsterixManagixAction(managixHomePath, ASTERIX_INSTANCE_NAME));
+        execs.add(new SleepAction(30000));
+        execs.add(new CreateAsterixManagixAction(managixHomePath, ASTERIX_INSTANCE_NAME, clusterConfigPath,
+                asterixConfigPath));
+
+        //ddl statements
+        execs.add(new SleepAction(15000));
+        // TODO: implement retry handler
+        execs.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve(LSMExperimentConstants.BASE_TYPES)));
+        doBuildDDL(execs);
+
+        //prepare io state action in NC node(s)
+        Map<String, List<String>> dgenPairs = readDatagenPairs(localExperimentRoot.resolve(
+                LSMExperimentConstants.DGEN_DIR).resolve(dgenFileName));
+        final Set<String> ncHosts = new HashSet<>();
+        for (List<String> ncHostList : dgenPairs.values()) {
+            for (String ncHost : ncHostList) {
+                ncHosts.add(ncHost.split(":")[0]);
+            }
+        }
+        if (statFile != null) {
+            ParallelActionSet ioCountActions = new ParallelActionSet();
+            for (String ncHost : ncHosts) {
+                ioCountActions.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+
+                    @Override
+                    protected String getCommand() {
+                        String cmd = "screen -d -m sh -c \"sar -b -u 1 > " + statFile + "\"";
+                        return cmd;
+                    }
+                });
+            }
+            execs.add(ioCountActions);
+        }
+
+        //prepare post ls action
+        SequentialActionList postLSAction = new SequentialActionList();
+        File file = new File(clusterConfigPath);
+        JAXBContext ctx = JAXBContext.newInstance(Cluster.class);
+        Unmarshaller unmarshaller = ctx.createUnmarshaller();
+        final Cluster cluster = (Cluster) unmarshaller.unmarshal(file);
+        String[] storageRoots = cluster.getIodevices().split(",");
+        for (String ncHost : ncHosts) {
+            for (final String sRoot : storageRoots) {
+                lsAction.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+                    @Override
+                    protected String getCommand() {
+                        return "ls -Rl " + sRoot;
+                    }
+                });
+                postLSAction.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+                    @Override
+                    protected String getCommand() {
+                        return "ls -Rl " + sRoot;
+                    }
+                });
+
+            }
+        }
+
+        //---------- main experiment body begins -----------
+
+        //load data into pidx 
+        execs.add(new TimedAction(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve(loadAQLFilePath))));
+
+        //---------- main experiment body ends -----------
+
+        //kill io state action
+        if (statFile != null) {
+            ParallelActionSet ioCountKillActions = new ParallelActionSet();
+            for (String ncHost : ncHosts) {
+                ioCountKillActions.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+
+                    @Override
+                    protected String getCommand() {
+                        String cmd = "screen -X -S `screen -list | grep Detached | awk '{print $1}'` quit";
+                        return cmd;
+                    }
+                });
+            }
+            execs.add(ioCountKillActions);
+        }
+
+        //total record count
+        execs.add(new SleepAction(10000));
+        if (countFileName != null) {
+            execs.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                    LSMExperimentConstants.AQL_DIR).resolve(countFileName)));
+        }
+
+        //add ls action
+        execs.add(postLSAction);
+
+        //kill asterix cc and nc
+        ParallelActionSet killCmds = new ParallelActionSet();
+        for (String ncHost : ncHosts) {
+            killCmds.add(new RemoteAsterixDriverKill(ncHost, username, sshKeyLocation));
+        }
+        killCmds.add(new RemoteAsterixDriverKill(restHost, username, sshKeyLocation));
+        execs.add(killCmds);
+
+        //stop asterix instance
+        execs.add(new StopAsterixManagixAction(managixHomePath, ASTERIX_INSTANCE_NAME));
+
+        //prepare to collect io state by putting the state file into asterix log dir
+        if (statFile != null) {
+            ParallelActionSet collectIOActions = new ParallelActionSet();
+            for (String ncHost : ncHosts) {
+                collectIOActions.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+
+                    @Override
+                    protected String getCommand() {
+                        String cmd = "cp " + statFile + " " + cluster.getLogDir();
+                        return cmd;
+                    }
+                });
+            }
+            execs.add(collectIOActions);
+        }
+
+        //collect cc and nc logs
+        execs.add(new LogAsterixManagixAction(managixHomePath, ASTERIX_INSTANCE_NAME, localExperimentRoot
+                .resolve(LSMExperimentConstants.LOG_DIR + "-" + logDirSuffix).resolve(getName()).toString()));
+
+        e.addBody(execs);
+    }
+
+    protected Map<String, List<String>> readDatagenPairs(Path p) throws IOException {
+        Map<String, List<String>> dgenPairs = new HashMap<>();
+        Scanner s = new Scanner(p, StandardCharsets.UTF_8.name());
+        try {
+            while (s.hasNextLine()) {
+                String line = s.nextLine();
+                String[] pair = line.split("\\s+");
+                List<String> vals = dgenPairs.get(pair[0]);
+                if (vals == null) {
+                    vals = new ArrayList<>();
+                    dgenPairs.put(pair[0], vals);
+                }
+                vals.add(pair[1]);
+            }
+        } finally {
+            s.close();
+        }
+        return dgenPairs;
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder.java
new file mode 100644
index 0000000..9720346
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder.java
@@ -0,0 +1,532 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Scanner;
+import java.util.Set;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.asterix.event.schema.cluster.Cluster;
+import org.apache.asterix.experiment.action.base.IAction;
+import org.apache.asterix.experiment.action.base.ParallelActionSet;
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.AbstractRemoteExecutableAction;
+import org.apache.asterix.experiment.action.derived.CloseOutputStreamAction;
+import org.apache.asterix.experiment.action.derived.ManagixActions.LogAsterixManagixAction;
+import org.apache.asterix.experiment.action.derived.ManagixActions.StartAsterixManagixAction;
+import org.apache.asterix.experiment.action.derived.ManagixActions.StopAsterixManagixAction;
+import org.apache.asterix.experiment.action.derived.RemoteAsterixDriverKill;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.action.derived.RunAQLStringAction;
+import org.apache.asterix.experiment.action.derived.SleepAction;
+import org.apache.asterix.experiment.action.derived.TimedAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.hyracks.api.util.ExperimentProfilerUtils;
+
+/**
+ * This class is used to create experiments for spatial index static data evaluation, that is, no ingestion is involved.
+ * Also, there is no orchestration server involved in this experiment builder.
+ */
+public abstract class AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder extends AbstractExperimentBuilder {
+
+    private static final boolean PROFILE_JOB_LAUCHING_OVERHEAD = false;
+
+    private static final String ASTERIX_INSTANCE_NAME = "a1";
+    private static final int SKIP_LINE_COUNT = 223;
+    private static final int CACHE_WARM_UP_QUERY_COUNT = 500;
+    private static final int SELECT_QUERY_COUNT = 5000;
+    private static final int JOIN_QUERY_COUNT = 1000;
+
+    private static final int JOIN_CANDIDATE_COUNT = 100;
+    private static final int MAX_QUERY_SEED = 10000;
+
+    private int querySeed = 0;
+
+    private int queryCount = 0;
+
+    private final String logDirSuffix;
+
+    protected final HttpClient httpClient;
+
+    protected final String restHost;
+
+    protected final int restPort;
+
+    private final String managixHomePath;
+
+    protected final String javaHomePath;
+
+    protected final Path localExperimentRoot;
+
+    protected final String username;
+
+    protected final String sshKeyLocation;
+
+    private final int duration;
+
+    private final String clusterConfigFileName;
+
+    private final String ingestFileName;
+
+    protected final String dgenFileName;
+
+    private final String countFileName;
+
+    private final String statFile;
+
+    protected final SequentialActionList lsAction;
+
+    protected final String openStreetMapFilePath;
+
+    protected final int locationSampleInterval;
+
+    protected final String createAQLFilePath;
+
+    protected final String querySeedFilePath;
+
+    private final float[] radiusType = new float[] { 0.00001f, 0.0001f, 0.001f, 0.01f, 0.1f };
+    private int radiusIter = 0;
+    private final Random randGen;
+    private BufferedReader br;
+    private final boolean isIndexOnlyPlan;
+    private String outputFilePath;
+    private FileOutputStream outputFos;
+
+    public AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder(String name, LSMExperimentSetRunnerConfig config,
+            String clusterConfigFileName, String ingestFileName, String dgenFileName, String countFileName,
+            String createAQLFileName, boolean isIndexOnlyPlan) {
+        super(name);
+        this.logDirSuffix = config.getLogDirSuffix();
+        this.httpClient = new DefaultHttpClient();
+        this.restHost = config.getRESTHost();
+        this.restPort = config.getRESTPort();
+        this.managixHomePath = config.getManagixHome();
+        this.javaHomePath = config.getJavaHome();
+        this.localExperimentRoot = Paths.get(config.getLocalExperimentRoot());
+        this.username = config.getUsername();
+        this.sshKeyLocation = config.getSSHKeyLocation();
+        this.duration = config.getDuration();
+        this.clusterConfigFileName = clusterConfigFileName;
+        this.ingestFileName = ingestFileName;
+        this.dgenFileName = dgenFileName;
+        this.countFileName = countFileName;
+        this.statFile = config.getStatFile();
+        this.lsAction = new SequentialActionList();
+        this.openStreetMapFilePath = config.getOpenStreetMapFilePath();
+        this.locationSampleInterval = config.getLocationSampleInterval();
+        this.createAQLFilePath = createAQLFileName;
+        this.querySeedFilePath = config.getQuerySeedFilePath();
+        this.randGen = new Random();
+        this.isIndexOnlyPlan = isIndexOnlyPlan;
+    }
+
+    protected void doPost(SequentialActionList seq) {
+    }
+
+    protected void doBuildDataGen(SequentialActionList seq, final Map<String, List<String>> dgenPairs) throws Exception {
+    }
+
+    @Override
+    protected void doBuild(Experiment e) throws Exception {
+        SequentialActionList execs = new SequentialActionList();
+
+        String clusterConfigPath = localExperimentRoot.resolve(LSMExperimentConstants.CONFIG_DIR)
+                .resolve(clusterConfigFileName).toString();
+        String asterixConfigPath = localExperimentRoot.resolve(LSMExperimentConstants.CONFIG_DIR)
+                .resolve(LSMExperimentConstants.ASTERIX_CONFIGURATION).toString();
+
+        //start asterix instance
+        execs.add(new StartAsterixManagixAction(managixHomePath, ASTERIX_INSTANCE_NAME));
+        execs.add(new SleepAction(30000));
+
+        //prepare io state action in NC node(s)
+        Map<String, List<String>> dgenPairs = readDatagenPairs(localExperimentRoot.resolve(
+                LSMExperimentConstants.DGEN_DIR).resolve(dgenFileName));
+        final Set<String> ncHosts = new HashSet<>();
+        for (List<String> ncHostList : dgenPairs.values()) {
+            for (String ncHost : ncHostList) {
+                ncHosts.add(ncHost.split(":")[0]);
+            }
+        }
+        if (statFile != null) {
+            ParallelActionSet ioCountActions = new ParallelActionSet();
+            for (String ncHost : ncHosts) {
+                ioCountActions.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+
+                    @Override
+                    protected String getCommand() {
+                        String cmd = "screen -d -m sh -c \"sar -b -u 1 > " + statFile + "\"";
+                        return cmd;
+                    }
+                });
+            }
+            execs.add(ioCountActions);
+        }
+
+        //prepare post ls action
+        SequentialActionList postLSAction = new SequentialActionList();
+        File file = new File(clusterConfigPath);
+        JAXBContext ctx = JAXBContext.newInstance(Cluster.class);
+        Unmarshaller unmarshaller = ctx.createUnmarshaller();
+        final Cluster cluster = (Cluster) unmarshaller.unmarshal(file);
+        String[] storageRoots = cluster.getIodevices().split(",");
+        for (String ncHost : ncHosts) {
+            for (final String sRoot : storageRoots) {
+                lsAction.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+                    @Override
+                    protected String getCommand() {
+                        return "ls -Rl " + sRoot;
+                    }
+                });
+                postLSAction.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+                    @Override
+                    protected String getCommand() {
+                        return "ls -Rl " + sRoot;
+                    }
+                });
+
+            }
+        }
+
+        //---------- main experiment body begins -----------
+
+        try {
+            outputFilePath = openStreetMapFilePath.substring(0, openStreetMapFilePath.lastIndexOf(File.separator))
+                    + File.separator + "QueryGenResult-" + getName() + "-"
+                    + Inet4Address.getLocalHost().getHostAddress() + ".txt";
+            outputFos = ExperimentProfilerUtils.openOutputFile(outputFilePath);
+        } catch (Exception e1) {
+            e1.printStackTrace();
+            return;
+        }
+
+        //delete all existing secondary indexes if any
+        execs.add(new RunAQLStringAction(httpClient, restHost, restPort,
+                "use dataverse experiments; drop index Tweets.dhbtreeLocation;", outputFos));
+        execs.add(new RunAQLStringAction(httpClient, restHost, restPort,
+                "use dataverse experiments; drop index Tweets.dhvbtreeLocation;", outputFos));
+        execs.add(new RunAQLStringAction(httpClient, restHost, restPort,
+                "use dataverse experiments; drop index Tweets.rtreeLocation;", outputFos));
+        execs.add(new RunAQLStringAction(httpClient, restHost, restPort,
+                "use dataverse experiments; drop index Tweets.shbtreeLocation;", outputFos));
+        execs.add(new RunAQLStringAction(httpClient, restHost, restPort,
+                "use dataverse experiments; drop index Tweets.sifLocation;", outputFos));
+
+        //create secondary index 
+        execs.add(new TimedAction(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve(createAQLFilePath), outputFos), outputFos));
+
+        //run count query for cleaning up OS buffer cache
+        if (countFileName != null) {
+            execs.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                    LSMExperimentConstants.AQL_DIR).resolve(countFileName), outputFos));
+        }
+
+        //run cache warm-up queries: run CACHE_WARM_UP_QUERY_COUNT select queries
+        br = new BufferedReader(new FileReader(querySeedFilePath));
+        radiusIter = 0;
+        for (int i = 0; i < CACHE_WARM_UP_QUERY_COUNT; i++) {
+            execs.add(getSelectQuery(isIndexOnlyPlan));
+        }
+
+        radiusIter = 0;
+        //run queries for measurement: run SELECT_QUERY_COUNT select queries
+        for (int i = 0; i < SELECT_QUERY_COUNT; i++) {
+            execs.add(getSelectQuery(isIndexOnlyPlan));
+        }
+
+        radiusIter = 0;
+        //run queries for measurement: run JOIN_QUERY_COUNT join queries
+        for (int i = 0; i < JOIN_QUERY_COUNT; i++) {
+            execs.add(getJoinQuery(isIndexOnlyPlan));
+        }
+
+        //---------- main experiment body ends -----------
+
+        //kill io state action
+        //        if (statFile != null) {
+        //            ParallelActionSet ioCountKillActions = new ParallelActionSet();
+        //            for (String ncHost : ncHosts) {
+        //                ioCountKillActions.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+        //
+        //                    @Override
+        //                    protected String getCommand() {
+        //                        String cmd = "screen -X -S `screen -list | grep Detached | awk '{print $1}'` quit";
+        //                        return cmd;
+        //                    }
+        //                });
+        //            }
+        //            execs.add(ioCountKillActions);
+        //        }
+
+        //add ls action
+        execs.add(postLSAction);
+
+        //kill asterix cc and nc
+        ParallelActionSet killCmds = new ParallelActionSet();
+        for (String ncHost : ncHosts) {
+            killCmds.add(new RemoteAsterixDriverKill(ncHost, username, sshKeyLocation));
+        }
+        killCmds.add(new RemoteAsterixDriverKill(restHost, username, sshKeyLocation));
+        execs.add(killCmds);
+
+        //stop asterix instance
+        execs.add(new StopAsterixManagixAction(managixHomePath, ASTERIX_INSTANCE_NAME));
+
+        //prepare to collect io state by putting the state file into asterix log dir
+        if (statFile != null) {
+            ParallelActionSet collectIOActions = new ParallelActionSet();
+            for (String ncHost : ncHosts) {
+                collectIOActions.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+
+                    @Override
+                    protected String getCommand() {
+                        String cmd = "cp " + statFile + " " + cluster.getLogDir();
+                        return cmd;
+                    }
+                });
+            }
+            execs.add(collectIOActions);
+        }
+
+        //collect profile information
+        //        if (ExperimentProfiler.PROFILE_MODE) {
+        //            if (!SpatialIndexProfiler.PROFILE_HOME_DIR.contentEquals(cluster.getLogDir())) {
+        //                ParallelActionSet collectProfileInfo = new ParallelActionSet();
+        //                for (String ncHost : ncHosts) {
+        //                    collectProfileInfo.add(new AbstractRemoteExecutableAction(ncHost, username, sshKeyLocation) {
+        //                        @Override
+        //                        protected String getCommand() {
+        //                            String cmd = "mv " + SpatialIndexProfiler.PROFILE_HOME_DIR + "*.txt " + cluster.getLogDir();
+        //                            return cmd;
+        //                        }
+        //                    });
+        //                }
+        //                execs.add(collectProfileInfo);
+        //            }
+        //        }
+
+        //collect cc and nc logs
+        execs.add(new LogAsterixManagixAction(managixHomePath, ASTERIX_INSTANCE_NAME, localExperimentRoot
+                .resolve(LSMExperimentConstants.LOG_DIR + "-" + logDirSuffix).resolve(getName()).toString()));
+
+        //get query result file
+        final String queryResultFilePath = outputFilePath;
+        execs.add(new AbstractRemoteExecutableAction(restHost, username, sshKeyLocation) {
+            @Override
+            protected String getCommand() {
+                String cmd = "mv "
+                        + queryResultFilePath
+                        + " "
+                        + localExperimentRoot.resolve(LSMExperimentConstants.LOG_DIR + "-" + logDirSuffix)
+                                .resolve(getName()).toString();
+                return cmd;
+            }
+        });
+        //close the outputStream
+        execs.add(new CloseOutputStreamAction(outputFos));
+
+        e.addBody(execs);
+    }
+
+    protected Map<String, List<String>> readDatagenPairs(Path p) throws IOException {
+        Map<String, List<String>> dgenPairs = new HashMap<>();
+        Scanner s = new Scanner(p, StandardCharsets.UTF_8.name());
+        try {
+            while (s.hasNextLine()) {
+                String line = s.nextLine();
+                String[] pair = line.split("\\s+");
+                List<String> vals = dgenPairs.get(pair[0]);
+                if (vals == null) {
+                    vals = new ArrayList<>();
+                    dgenPairs.put(pair[0], vals);
+                }
+                vals.add(pair[1]);
+            }
+        } finally {
+            s.close();
+        }
+        return dgenPairs;
+    }
+
+    private SequentialActionList getSelectQuery(boolean isIndexOnlyPlan) throws IOException {
+        //prepare radius and center point
+        int skipLineCount = SKIP_LINE_COUNT;
+        int lineCount = 0;
+        String line = null;;
+
+        querySeed += SKIP_LINE_COUNT;
+        if (querySeed > MAX_QUERY_SEED) {
+            querySeed -= MAX_QUERY_SEED;
+        }
+
+        while (lineCount < skipLineCount) {
+            if ((line = br.readLine()) == null) {
+                //reopen file
+                br.close();
+                br = new BufferedReader(new FileReader(querySeedFilePath));
+                line = br.readLine();
+            }
+            lineCount++;
+        }
+
+        int beginIdx = line.indexOf("(", line.indexOf("point"));
+        int endIdx = line.indexOf(")", line.indexOf("point")) + 1;
+        String point = line.substring(beginIdx, endIdx);
+
+        //create action
+        SequentialActionList sAction = new SequentialActionList();
+        IAction queryAction = new TimedAction(new RunAQLStringAction(httpClient, restHost, restPort, getSelectQueryAQL(
+                radiusType[radiusIter++ % radiusType.length], point, isIndexOnlyPlan), outputFos), outputFos);
+        sAction.add(queryAction);
+
+        return sAction;
+    }
+
+    private String getSelectQueryAQL(float radius, String point, boolean isIndexOnlyPlan) {
+        if (PROFILE_JOB_LAUCHING_OVERHEAD) {
+            Random random = new Random();
+            int btreeExtraFieldKey = random.nextInt();
+            int rangeSize = (int) (radius * 100000000L);
+            if (btreeExtraFieldKey == Integer.MIN_VALUE) {
+                btreeExtraFieldKey = Integer.MIN_VALUE + 1;
+            }
+            if (btreeExtraFieldKey + rangeSize >= Integer.MAX_VALUE) {
+                btreeExtraFieldKey = Integer.MAX_VALUE - rangeSize - 1;
+            }
+
+            StringBuilder sb = new StringBuilder();
+            sb.append("use dataverse experiments; ");
+            sb.append("count( ");
+            sb.append("for $x in dataset Tweets").append(" ");
+            sb.append("where $x.btree-extra-field1 > int32(\"" + btreeExtraFieldKey
+                    + "\") and $x.btree-extra-field1 < int32(\"" + (btreeExtraFieldKey + rangeSize) + "\")");
+            sb.append("return $x ");
+            sb.append(");");
+
+            System.out.println("[squery" + (queryCount++) + "]" + sb.toString());
+
+            return sb.toString();
+        } else {
+            StringBuilder sb = new StringBuilder();
+            sb.append("use dataverse experiments; ");
+            sb.append("count( ");
+            sb.append("for $x in dataset Tweets").append(" ");
+            sb.append("let $n :=  create-circle( ");
+            sb.append("point").append(point).append(" ");
+            sb.append(", ");
+            sb.append(String.format("%f", radius));
+            sb.append(" ) ");
+            if (isIndexOnlyPlan) {
+                sb.append("where spatial-intersect($x.sender-location, $n) ");
+            } else {
+                sb.append("where spatial-intersect($x.sender-location, $n) and $x.btree-extra-field1 <= int32(\"2147483647\") ");
+            }
+            sb.append("return $x ");
+            sb.append(");");
+
+            System.out.println("[squery" + (queryCount++) + "]" + sb.toString());
+
+            return sb.toString();
+        }
+    }
+
+    private SequentialActionList getJoinQuery(boolean isIndexOnlyPlan) {
+        querySeed += SKIP_LINE_COUNT;
+        if (querySeed > MAX_QUERY_SEED) {
+            querySeed -= MAX_QUERY_SEED;
+        }
+
+        int lowId = querySeed * 10000 + 1;
+        int highId = (querySeed + JOIN_CANDIDATE_COUNT) * 10000 + 1;
+
+        //create action
+        SequentialActionList sAction = new SequentialActionList();
+        IAction queryAction = new TimedAction(new RunAQLStringAction(httpClient, restHost, restPort, getJoinQueryAQL(
+                radiusType[radiusIter++ % (radiusType.length - 1)], lowId, highId, isIndexOnlyPlan), outputFos),
+                outputFos);
+        sAction.add(queryAction);
+
+        return sAction;
+    }
+
+    private String getJoinQueryAQL(float radius, int lowId, int highId, boolean isIndexOnlyPlan) {
+        if (PROFILE_JOB_LAUCHING_OVERHEAD) {
+            Random random = new Random();
+            int btreeExtraFieldKey = random.nextInt();
+            if (btreeExtraFieldKey == Integer.MIN_VALUE) {
+                btreeExtraFieldKey = Integer.MIN_VALUE + 1;
+            }
+
+            StringBuilder sb = new StringBuilder();
+            sb.append("use dataverse experiments; ");
+            sb.append("count( ");
+            sb.append("for $x in dataset Tweets").append(" ");
+            sb.append("where $x.tweetid = int64(\"" + btreeExtraFieldKey + "\")");
+            sb.append("return $x ");
+            sb.append(");");
+
+            System.out.println("[squery" + (queryCount++) + "]" + sb.toString());
+
+            return sb.toString();
+        } else {
+            StringBuilder sb = new StringBuilder();
+            sb.append(" use dataverse experiments; \n");
+            sb.append(" count( \n");
+            sb.append(" for $x in dataset JoinSeedTweets").append(" \n");
+            sb.append(" let $area := create-circle($x.sender-location, ").append(String.format("%f", radius))
+                    .append(" ) \n");
+            sb.append(" for $y in dataset Tweets \n");
+            sb.append(" where $x.tweetid >= int64(\"" + lowId + "\") ").append(
+                    "and $x.tweetid < int64(\"" + highId + "\") and ");
+            if (isIndexOnlyPlan) {
+                sb.append(" spatial-intersect($y.sender-location, $area) \n");
+            } else {
+                sb.append(" spatial-intersect($y.sender-location, $area) and $y.btree-extra-field1 <= int32(\"2147483647\")  \n");
+            }
+            sb.append(" return $y \n");
+            sb.append(" );\n");
+
+            System.out.println("[jquery" + (queryCount++) + "]" + sb.toString());
+
+            return sb.toString();
+        }
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment.java
new file mode 100644
index 0000000..3faf195
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment.java
@@ -0,0 +1,58 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.asterix.experiment.action.base.AbstractAction;
+import org.apache.asterix.experiment.action.base.IAction;
+
+public class Experiment extends AbstractAction {
+
+    private static final Logger LOGGER = Logger.getLogger(Experiment.class.getName());
+
+    private final String name;
+
+    private IAction body;
+
+    public Experiment(String name) {
+        this.name = name;
+    }
+
+    public void addBody(IAction exec) {
+        body = exec;
+    }
+
+    @Override
+    protected void doPerform() throws Exception {
+        if (body != null) {
+            if (LOGGER.isLoggable(Level.INFO)) {
+                LOGGER.info("Running experiment: " + name);
+            }
+            body.perform();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment1ABuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment1ABuilder.java
new file mode 100644
index 0000000..f7d2039
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment1ABuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment1ABuilder extends AbstractExperiment1Builder {
+
+    public Experiment1ABuilder(LSMExperimentSetRunnerConfig config) {
+        super("1A", config, "1node.xml", "base_1_ingest.aql", "1.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment1BBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment1BBuilder.java
new file mode 100644
index 0000000..17e288f
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment1BBuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment1BBuilder extends AbstractExperiment1Builder {
+
+    public Experiment1BBuilder(LSMExperimentSetRunnerConfig config) {
+        super("1B", config, "2node.xml", "base_2_ingest.aql", "2.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment1CBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment1CBuilder.java
new file mode 100644
index 0000000..efc5003
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment1CBuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment1CBuilder extends AbstractExperiment1Builder {
+
+    public Experiment1CBuilder(LSMExperimentSetRunnerConfig config) {
+        super("1C", config, "4node.xml", "base_4_ingest.aql", "4.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment1DBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment1DBuilder.java
new file mode 100644
index 0000000..d6d358b
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment1DBuilder.java
@@ -0,0 +1,29 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment1DBuilder extends AbstractExperiment1Builder {
+
+    public Experiment1DBuilder(LSMExperimentSetRunnerConfig config) {
+        super("1D", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2A1Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2A1Builder.java
new file mode 100644
index 0000000..3fc9cc7
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2A1Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2A1Builder extends AbstractExperiment2ABuilder {
+
+    public Experiment2A1Builder(LSMExperimentSetRunnerConfig config) {
+        super("2A1", config, "1node.xml", "base_1_ingest.aql", "1.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2A2Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2A2Builder.java
new file mode 100644
index 0000000..2c08ed3
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2A2Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2A2Builder extends AbstractExperiment2ABuilder {
+
+    public Experiment2A2Builder(LSMExperimentSetRunnerConfig config) {
+        super("2A2", config, "2node.xml", "base_2_ingest.aql", "2.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2A4Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2A4Builder.java
new file mode 100644
index 0000000..a319687
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2A4Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2A4Builder extends AbstractExperiment2ABuilder {
+
+    public Experiment2A4Builder(LSMExperimentSetRunnerConfig config) {
+        super("2A4", config, "4node.xml", "base_4_ingest.aql", "4.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2A8Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2A8Builder.java
new file mode 100644
index 0000000..3946ea3
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2A8Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2A8Builder extends AbstractExperiment2ABuilder {
+
+    public Experiment2A8Builder(LSMExperimentSetRunnerConfig config) {
+        super("2A8", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2B1Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2B1Builder.java
new file mode 100644
index 0000000..e1f39b2
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2B1Builder.java
@@ -0,0 +1,29 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2B1Builder extends AbstractExperiment2BBuilder {
+
+    public Experiment2B1Builder(LSMExperimentSetRunnerConfig config) {
+        super("2B1", config, "1node.xml", "base_1_ingest.aql", "1.dgen");
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2B2Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2B2Builder.java
new file mode 100644
index 0000000..42f23d5
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2B2Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2B2Builder extends AbstractExperiment2BBuilder {
+
+    public Experiment2B2Builder(LSMExperimentSetRunnerConfig config) {
+        super("2B2", config, "2node.xml", "base_2_ingest.aql", "2.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2B4Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2B4Builder.java
new file mode 100644
index 0000000..f644fd8
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2B4Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2B4Builder extends AbstractExperiment2BBuilder {
+
+    public Experiment2B4Builder(LSMExperimentSetRunnerConfig config) {
+        super("2B4", config, "4node.xml", "base_4_ingest.aql", "4.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2B8Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2B8Builder.java
new file mode 100644
index 0000000..6264513
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2B8Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2B8Builder extends AbstractExperiment2BBuilder {
+
+    public Experiment2B8Builder(LSMExperimentSetRunnerConfig config) {
+        super("2B8", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2C1Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2C1Builder.java
new file mode 100644
index 0000000..81c5428
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2C1Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2C1Builder extends AbstractExperiment2CBuilder {
+
+    public Experiment2C1Builder(LSMExperimentSetRunnerConfig config) {
+        super("2C1", config, "1node.xml", "base_1_ingest.aql", "1.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2C2Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2C2Builder.java
new file mode 100644
index 0000000..d1ff1d3
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2C2Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2C2Builder extends AbstractExperiment2CBuilder {
+
+    public Experiment2C2Builder(LSMExperimentSetRunnerConfig config) {
+        super("2C2", config, "2node.xml", "base_2_ingest.aql", "2.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2C4Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2C4Builder.java
new file mode 100644
index 0000000..a6594d3
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2C4Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2C4Builder extends AbstractExperiment2CBuilder {
+
+    public Experiment2C4Builder(LSMExperimentSetRunnerConfig config) {
+        super("2C4", config, "4node.xml", "base_4_ingest.aql", "4.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2C8Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2C8Builder.java
new file mode 100644
index 0000000..bccd0a5
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2C8Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2C8Builder extends AbstractExperiment2CBuilder {
+
+    public Experiment2C8Builder(LSMExperimentSetRunnerConfig config) {
+        super("2C8", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2D1Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2D1Builder.java
new file mode 100644
index 0000000..02d9015
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2D1Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2D1Builder extends AbstractExperiment2DBuilder {
+
+    public Experiment2D1Builder(LSMExperimentSetRunnerConfig config) {
+        super("2D1", config, "1node.xml", "base_1_ingest.aql", "1.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2D2Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2D2Builder.java
new file mode 100644
index 0000000..1e65877
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2D2Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2D2Builder extends AbstractExperiment2DBuilder {
+
+    public Experiment2D2Builder(LSMExperimentSetRunnerConfig config) {
+        super("2D2", config, "2node.xml", "base_2_ingest.aql", "2.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2D4Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2D4Builder.java
new file mode 100644
index 0000000..4bca31c
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2D4Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2D4Builder extends AbstractExperiment2DBuilder {
+
+    public Experiment2D4Builder(LSMExperimentSetRunnerConfig config) {
+        super("2D4", config, "4node.xml", "base_4_ingest.aql", "4.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2D8Builder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2D8Builder.java
new file mode 100644
index 0000000..779aefd
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment2D8Builder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment2D8Builder extends AbstractExperiment2DBuilder {
+
+    public Experiment2D8Builder(LSMExperimentSetRunnerConfig config) {
+        super("2D8", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment3ABuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment3ABuilder.java
new file mode 100644
index 0000000..b44b82d
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment3ABuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment3ABuilder extends AbstractExperiment3Builder {
+
+    public Experiment3ABuilder(LSMExperimentSetRunnerConfig config) {
+        super("3A", config, "1node.xml", "base_1_ingest.aql", "1.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment3BBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment3BBuilder.java
new file mode 100644
index 0000000..f54154a
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment3BBuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment3BBuilder extends AbstractExperiment3Builder {
+
+    public Experiment3BBuilder(LSMExperimentSetRunnerConfig config) {
+        super("3B", config, "2node.xml", "base_2_ingest.aql", "2.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment3CBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment3CBuilder.java
new file mode 100644
index 0000000..526d65e
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment3CBuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment3CBuilder extends AbstractExperiment3Builder {
+
+    public Experiment3CBuilder(LSMExperimentSetRunnerConfig config) {
+        super("3C", config, "4node.xml", "base_4_ingest.aql", "4.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment3DBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment3DBuilder.java
new file mode 100644
index 0000000..4d59dec
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment3DBuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment3DBuilder extends AbstractExperiment3Builder {
+
+    public Experiment3DBuilder(LSMExperimentSetRunnerConfig config) {
+        super("3D", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment4ABuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment4ABuilder.java
new file mode 100644
index 0000000..7a500e6
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment4ABuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment4ABuilder extends AbstractExperiment4Builder {
+
+    public Experiment4ABuilder(LSMExperimentSetRunnerConfig config) {
+        super("4A", config);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("4_1.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment4BBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment4BBuilder.java
new file mode 100644
index 0000000..bc2ffc8
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment4BBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment4BBuilder extends AbstractExperiment4Builder {
+
+    public Experiment4BBuilder(LSMExperimentSetRunnerConfig config) {
+        super("4B", config);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("4_2.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment4CBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment4CBuilder.java
new file mode 100644
index 0000000..2215b8a
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment4CBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment4CBuilder extends AbstractExperiment4Builder {
+
+    public Experiment4CBuilder(LSMExperimentSetRunnerConfig config) {
+        super("4C", config);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("4_4.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment4DBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment4DBuilder.java
new file mode 100644
index 0000000..86bb940
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment4DBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment4DBuilder extends AbstractExperiment4Builder {
+
+    public Experiment4DBuilder(LSMExperimentSetRunnerConfig config) {
+        super("4D", config);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("4_8.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment5ABuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment5ABuilder.java
new file mode 100644
index 0000000..ce9f95f
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment5ABuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment5ABuilder extends AbstractLSMBaseExperimentBuilder {
+
+    public Experiment5ABuilder(LSMExperimentSetRunnerConfig config) {
+        super("5A", config, "8node.xml", "5_1_ingest.aql", "5_1.dgen", "5_1_count.aql");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("5_1.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment5BBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment5BBuilder.java
new file mode 100644
index 0000000..577ecf1
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment5BBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment5BBuilder extends AbstractLSMBaseExperimentBuilder {
+
+    public Experiment5BBuilder(LSMExperimentSetRunnerConfig config) {
+        super("5B", config, "8node.xml", "5_2_ingest.aql", "5_2.dgen", "5_2_count.aql");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("5_2.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment5CBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment5CBuilder.java
new file mode 100644
index 0000000..a78379b
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment5CBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment5CBuilder extends AbstractLSMBaseExperimentBuilder {
+
+    public Experiment5CBuilder(LSMExperimentSetRunnerConfig config) {
+        super("5C", config, "8node.xml", "5_3_ingest.aql", "5_3.dgen", "5_3_count.aql");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("5_3.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment5DBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment5DBuilder.java
new file mode 100644
index 0000000..af02a8d
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment5DBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment5DBuilder extends AbstractLSMBaseExperimentBuilder {
+
+    public Experiment5DBuilder(LSMExperimentSetRunnerConfig config) {
+        super("5D", config, "8node.xml", "5_4_ingest.aql", "5_4.dgen", "5_4_count.aql");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("5_4.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment6ABuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment6ABuilder.java
new file mode 100644
index 0000000..92f4bbb
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment6ABuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment6ABuilder extends AbstractExperiment6Builder {
+
+    public Experiment6ABuilder(LSMExperimentSetRunnerConfig config) {
+        super("6A", config);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("6_a.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment6BBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment6BBuilder.java
new file mode 100644
index 0000000..936b804
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment6BBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment6BBuilder extends AbstractExperiment6Builder {
+
+    public Experiment6BBuilder(LSMExperimentSetRunnerConfig config) {
+        super("6B", config);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("6_b.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment6CBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment6CBuilder.java
new file mode 100644
index 0000000..6e1b7f7
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment6CBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment6CBuilder extends AbstractExperiment6Builder {
+
+    public Experiment6CBuilder(LSMExperimentSetRunnerConfig config) {
+        super("6C", config);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("6_c.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment7ABuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment7ABuilder.java
new file mode 100644
index 0000000..828006d
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment7ABuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment7ABuilder extends AbstractExperiment7Builder {
+
+    public Experiment7ABuilder(LSMExperimentSetRunnerConfig config) {
+        super("7A", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("8_a.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment7BBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment7BBuilder.java
new file mode 100644
index 0000000..513069a
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment7BBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment7BBuilder extends AbstractExperiment7Builder {
+
+    public Experiment7BBuilder(LSMExperimentSetRunnerConfig config) {
+        super("7B", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("8_b.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment7DBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment7DBuilder.java
new file mode 100644
index 0000000..0a2cf57
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment7DBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment7DBuilder extends AbstractExperiment7Builder {
+
+    public Experiment7DBuilder(LSMExperimentSetRunnerConfig config) {
+        super("7D", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("8_d.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment8ABuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment8ABuilder.java
new file mode 100644
index 0000000..e7cb68f
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment8ABuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment8ABuilder extends AbstractExperiment8Builder {
+
+    public Experiment8ABuilder(LSMExperimentSetRunnerConfig config) {
+        super("8A", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("8_a.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment8BBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment8BBuilder.java
new file mode 100644
index 0000000..f97d431
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment8BBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment8BBuilder extends AbstractExperiment8Builder {
+
+    public Experiment8BBuilder(LSMExperimentSetRunnerConfig config) {
+        super("8B", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("8_b.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment8CBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment8CBuilder.java
new file mode 100644
index 0000000..d578fbb
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment8CBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment8CBuilder extends AbstractExperiment8Builder {
+
+    public Experiment8CBuilder(LSMExperimentSetRunnerConfig config) {
+        super("8C", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("8_c.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment8DBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment8DBuilder.java
new file mode 100644
index 0000000..94f9351
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment8DBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment8DBuilder extends AbstractExperiment8Builder {
+
+    public Experiment8DBuilder(LSMExperimentSetRunnerConfig config) {
+        super("8D", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("8_d.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment9ABuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment9ABuilder.java
new file mode 100644
index 0000000..50417f9
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment9ABuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment9ABuilder extends AbstractExperiment9Builder {
+
+    public Experiment9ABuilder(LSMExperimentSetRunnerConfig config) {
+        super("9A", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("8_a.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment9BBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment9BBuilder.java
new file mode 100644
index 0000000..0020623
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment9BBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment9BBuilder extends AbstractExperiment9Builder {
+
+    public Experiment9BBuilder(LSMExperimentSetRunnerConfig config) {
+        super("9B", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("8_b.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment9DBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment9DBuilder.java
new file mode 100644
index 0000000..f9fd10e
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/Experiment9DBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class Experiment9DBuilder extends AbstractExperiment9Builder {
+
+    public Experiment9DBuilder(LSMExperimentSetRunnerConfig config) {
+        super("9D", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("8_d.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SingleNodeIngestionExperimentBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SingleNodeIngestionExperimentBuilder.java
new file mode 100644
index 0000000..38b9fcb
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SingleNodeIngestionExperimentBuilder.java
@@ -0,0 +1,71 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.DefaultHttpClient;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.SocketDataGeneratorExecutable;
+
+public class SingleNodeIngestionExperimentBuilder extends AbstractLocalExperimentBuilder {
+
+    private final String adapterHost;
+
+    private final int adapterPort;
+
+    private final HttpClient httpClient;
+
+    private final String restHost;
+
+    private final int restPort;
+
+    private final Path aqlFilePath;
+
+    public SingleNodeIngestionExperimentBuilder(String adapterHost, int adapterPort, String restHost, int restPort,
+            String aqlFilePath) {
+        super("Local Ingestion Experiment", 2);
+        this.adapterHost = adapterHost;
+        this.adapterPort = adapterPort;
+        httpClient = new DefaultHttpClient();
+        this.restHost = restHost;
+        this.restPort = restPort;
+        this.aqlFilePath = Paths.get(aqlFilePath);
+    }
+
+    @Override
+    protected void addPre(SequentialActionList pre) {
+        pre.add(new RunAQLFileAction(httpClient, restHost, restPort, aqlFilePath));
+    }
+
+    @Override
+    protected void addPost(SequentialActionList post) {
+
+    }
+
+    @Override
+    protected void doBuild(Experiment e) {
+        e.addBody(new SocketDataGeneratorExecutable(adapterHost, adapterPort));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1ADhbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1ADhbtreeBuilder.java
new file mode 100644
index 0000000..34a3555
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1ADhbtreeBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1ADhbtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1ADhbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1ADhbtree", config, "1node.xml", "base_1_ingest.aql", "1.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_dhbtree.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1ADhvbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1ADhvbtreeBuilder.java
new file mode 100644
index 0000000..9457671
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1ADhvbtreeBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1ADhvbtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1ADhvbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1ADhvbtree", config, "1node.xml", "base_1_ingest.aql", "1.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_dhvbtree.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1ARtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1ARtreeBuilder.java
new file mode 100644
index 0000000..1c21da5
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1ARtreeBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1ARtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1ARtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1ARtree", config, "1node.xml", "base_1_ingest.aql", "1.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_rtree.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1AShbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1AShbtreeBuilder.java
new file mode 100644
index 0000000..a238043
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1AShbtreeBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1AShbtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1AShbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1AShbtree", config, "1node.xml", "base_1_ingest.aql", "1.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_shbtree.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1ASifBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1ASifBuilder.java
new file mode 100644
index 0000000..9721d5e
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1ASifBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1ASifBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1ASifBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1ASif", config, "1node.xml", "base_1_ingest.aql", "1.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_sif.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BDhbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BDhbtreeBuilder.java
new file mode 100644
index 0000000..5f8446d
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BDhbtreeBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1BDhbtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1BDhbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1BDhbtree", config, "2node.xml", "base_2_ingest.aql", "2.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_dhbtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BDhvbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BDhvbtreeBuilder.java
new file mode 100644
index 0000000..4ff2576
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BDhvbtreeBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1BDhvbtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1BDhvbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1BDhvbtree", config, "2node.xml", "base_2_ingest.aql", "2.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_dhvbtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BRtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BRtreeBuilder.java
new file mode 100644
index 0000000..af22866
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BRtreeBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1BRtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1BRtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1BRtree", config, "2node.xml", "base_2_ingest.aql", "2.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_rtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BShbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BShbtreeBuilder.java
new file mode 100644
index 0000000..1c27a0b
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BShbtreeBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1BShbtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1BShbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1BShbtree", config, "2node.xml", "base_2_ingest.aql", "2.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_shbtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BSifBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BSifBuilder.java
new file mode 100644
index 0000000..e6a44cf
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1BSifBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1BSifBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1BSifBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1BSif", config, "2node.xml", "base_2_ingest.aql", "2.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_sif.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CDhbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CDhbtreeBuilder.java
new file mode 100644
index 0000000..2612ded
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CDhbtreeBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1CDhbtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1CDhbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1CDhbtree", config, "4node.xml", "base_4_ingest.aql", "4.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_dhbtree.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CDhvbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CDhvbtreeBuilder.java
new file mode 100644
index 0000000..a4a22df
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CDhvbtreeBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1CDhvbtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1CDhvbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1CDhvbtree", config, "4node.xml", "base_4_ingest.aql", "4.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_dhvbtree.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CRtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CRtreeBuilder.java
new file mode 100644
index 0000000..7ce9d77
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CRtreeBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1CRtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1CRtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1CRtree", config, "4node.xml", "base_4_ingest.aql", "4.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_rtree.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CShbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CShbtreeBuilder.java
new file mode 100644
index 0000000..d7bb6fc
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CShbtreeBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1CShbtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1CShbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1CShbtree", config, "4node.xml", "base_4_ingest.aql", "4.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_shbtree.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CSifBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CSifBuilder.java
new file mode 100644
index 0000000..25282dc
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1CSifBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1CSifBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1CSifBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1CSif", config, "4node.xml", "base_4_ingest.aql", "4.dgen");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_sif.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DDhbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DDhbtreeBuilder.java
new file mode 100644
index 0000000..a3f57d9
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DDhbtreeBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1DDhbtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1DDhbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1DDhbtree", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+    
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_dhbtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DDhvbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DDhvbtreeBuilder.java
new file mode 100644
index 0000000..02c8af9
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DDhvbtreeBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1DDhvbtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1DDhvbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1DDhvbtree", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+    
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_dhvbtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DRtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DRtreeBuilder.java
new file mode 100644
index 0000000..9f7ac45
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DRtreeBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1DRtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1DRtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1DRtree", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+    
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_rtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DShbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DShbtreeBuilder.java
new file mode 100644
index 0000000..3252fe1
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DShbtreeBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1DShbtreeBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1DShbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1DShbtree", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+    
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_shbtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DSifBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DSifBuilder.java
new file mode 100644
index 0000000..96889aa
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment1DSifBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment1DSifBuilder extends AbstractExperiment1Builder {
+
+    public SpatialIndexExperiment1DSifBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment1DSif", config, "8node.xml", "base_8_ingest.aql", "8.dgen");
+    }
+    
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_sif.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2DhbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2DhbtreeBuilder.java
new file mode 100644
index 0000000..667b9c2
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2DhbtreeBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment2DhbtreeBuilder extends AbstractSpatialIndexExperiment2Builder {
+
+    public SpatialIndexExperiment2DhbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment2Dhbtree", config, "1node.xml", "base_1_ingest_query.aql", "1.dgen", true);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_dhbtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2DhvbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2DhvbtreeBuilder.java
new file mode 100644
index 0000000..55c2140
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2DhvbtreeBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment2DhvbtreeBuilder extends AbstractSpatialIndexExperiment2Builder {
+
+    public SpatialIndexExperiment2DhvbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment2Dhvbtree", config, "1node.xml", "base_1_ingest_query.aql", "1.dgen", true);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_dhvbtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2RtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2RtreeBuilder.java
new file mode 100644
index 0000000..9188fbe
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2RtreeBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment2RtreeBuilder extends AbstractSpatialIndexExperiment2Builder {
+
+    public SpatialIndexExperiment2RtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment2Rtree", config, "1node.xml", "base_1_ingest_query.aql", "1.dgen", true);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_rtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2ShbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2ShbtreeBuilder.java
new file mode 100644
index 0000000..ec08453
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2ShbtreeBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment2ShbtreeBuilder extends AbstractSpatialIndexExperiment2Builder {
+
+    public SpatialIndexExperiment2ShbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment2Shbtree", config, "1node.xml", "base_1_ingest_query.aql", "1.dgen", true);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_shbtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2SifBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2SifBuilder.java
new file mode 100644
index 0000000..79353dc
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment2SifBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment2SifBuilder extends AbstractSpatialIndexExperiment2Builder {
+
+    public SpatialIndexExperiment2SifBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment2Sif", config, "1node.xml", "base_1_ingest_query.aql", "1.dgen", true);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_sif.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3DhbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3DhbtreeBuilder.java
new file mode 100644
index 0000000..4a6718f
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3DhbtreeBuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment3DhbtreeBuilder extends AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder {
+
+    public SpatialIndexExperiment3DhbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment3Dhbtree", config, "1node.xml", "base_1_ingest.aql", "1.dqgen", "count.aql",
+                "spatial_3_create_dhbtree.aql", true);
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3DhvbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3DhvbtreeBuilder.java
new file mode 100644
index 0000000..58cc03f
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3DhvbtreeBuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment3DhvbtreeBuilder extends AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder {
+
+    public SpatialIndexExperiment3DhvbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment3Dhvbtree", config, "8node.xml", "base_8_ingest.aql", "8.dqgen", "count.aql",
+                "spatial_3_create_dhvbtree.aql", true);
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3PIdxLoadBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3PIdxLoadBuilder.java
new file mode 100644
index 0000000..fbc63ac
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3PIdxLoadBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment3PIdxLoadBuilder extends AbstractSpatialIndexExperiment3PIdxLoadBuilder {
+
+    public SpatialIndexExperiment3PIdxLoadBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment3PIdxLoad", config, "8node.xml", "base_8_ingest.aql", "8.dqgen", "count.aql", "spatial_3_pidx_load.aql");
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_3.aql")));
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3RtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3RtreeBuilder.java
new file mode 100644
index 0000000..bcf5f8c
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3RtreeBuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment3RtreeBuilder extends AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder {
+
+    public SpatialIndexExperiment3RtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment3Rtree", config, "8node.xml", "base_8_ingest.aql", "8.dqgen", "count.aql",
+                "spatial_3_create_rtree.aql", true);
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3ShbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3ShbtreeBuilder.java
new file mode 100644
index 0000000..7b33ed7
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3ShbtreeBuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment3ShbtreeBuilder extends AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder {
+
+    public SpatialIndexExperiment3ShbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment3Shbtree", config, "8node.xml", "base_8_ingest.aql", "8.dqgen", "count.aql",
+                "spatial_3_create_shbtree.aql", true);
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3SifBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3SifBuilder.java
new file mode 100644
index 0000000..75a50c5
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment3SifBuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment3SifBuilder extends AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder {
+
+    public SpatialIndexExperiment3SifBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment3Sif", config, "8node.xml", "base_8_ingest.aql", "8.dqgen", "count.aql",
+                "spatial_3_create_sif.aql", true);
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4DhbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4DhbtreeBuilder.java
new file mode 100644
index 0000000..1fac7d0
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4DhbtreeBuilder.java
@@ -0,0 +1,31 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment4DhbtreeBuilder extends AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder {
+
+    //SpatialIndexExperiment4XXX is exactly the same as SpatialIndexExperiment3XXX except queries are non-index only plan queries.
+    public SpatialIndexExperiment4DhbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment4Dhbtree", config, "8node.xml", "base_8_ingest.aql", "8.dqgen", "count.aql",
+                "spatial_3_create_dhbtree.aql", false);
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4DhvbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4DhvbtreeBuilder.java
new file mode 100644
index 0000000..1579be0
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4DhvbtreeBuilder.java
@@ -0,0 +1,31 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment4DhvbtreeBuilder extends AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder {
+
+    //SpatialIndexExperiment4XXX is exactly the same as SpatialIndexExperiment3XXX except queries are non-index only plan queries.
+    public SpatialIndexExperiment4DhvbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment4Dhvbtree", config, "8node.xml", "base_8_ingest.aql", "8.dqgen", "count.aql",
+                "spatial_3_create_dhvbtree.aql", false);
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4RtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4RtreeBuilder.java
new file mode 100644
index 0000000..54cd9cc
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4RtreeBuilder.java
@@ -0,0 +1,31 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment4RtreeBuilder extends AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder {
+
+    //SpatialIndexExperiment4XXX is exactly the same as SpatialIndexExperiment3XXX except queries are non-index only plan queries.
+    public SpatialIndexExperiment4RtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment4Rtree", config, "8node.xml", "base_8_ingest.aql", "8.dqgen", "count.aql",
+                "spatial_3_create_rtree.aql", false);
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4ShbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4ShbtreeBuilder.java
new file mode 100644
index 0000000..91eef5e
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4ShbtreeBuilder.java
@@ -0,0 +1,31 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment4ShbtreeBuilder extends AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder {
+
+    //SpatialIndexExperiment4XXX is exactly the same as SpatialIndexExperiment3XXX except queries are non-index only plan queries.
+    public SpatialIndexExperiment4ShbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment4Shbtree", config, "8node.xml", "base_8_ingest.aql", "8.dqgen", "count.aql",
+                "spatial_3_create_shbtree.aql", false);
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4SifBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4SifBuilder.java
new file mode 100644
index 0000000..9043c5f
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment4SifBuilder.java
@@ -0,0 +1,31 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment4SifBuilder extends AbstractSpatialIndexExperiment3SIdxCreateAndQueryBuilder {
+
+    //SpatialIndexExperiment4XXX is exactly the same as SpatialIndexExperiment3XXX except queries are non-index only plan queries.
+    public SpatialIndexExperiment4SifBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment4Sif", config, "8node.xml", "base_8_ingest.aql", "8.dqgen", "count.aql",
+                "spatial_3_create_sif.aql", false);
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5DhbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5DhbtreeBuilder.java
new file mode 100644
index 0000000..74b00f3
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5DhbtreeBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment5DhbtreeBuilder extends AbstractSpatialIndexExperiment2Builder {
+
+    //SpatialIndexExperiment5XXX is exactly the same as SpatialIndexExperiment2XXX except queries are non-index only plan queries.
+    public SpatialIndexExperiment5DhbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment5Dhbtree", config, "1node.xml", "base_1_ingest_query.aql", "1.dgen", false);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_dhbtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5DhvbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5DhvbtreeBuilder.java
new file mode 100644
index 0000000..b665d1b
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5DhvbtreeBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment5DhvbtreeBuilder extends AbstractSpatialIndexExperiment2Builder {
+
+    //SpatialIndexExperiment5XXX is exactly the same as SpatialIndexExperiment2XXX except queries are non-index only plan queries.
+    public SpatialIndexExperiment5DhvbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment5Dhvbtree", config, "1node.xml", "base_1_ingest_query.aql", "1.dgen", false);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_dhvbtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5RtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5RtreeBuilder.java
new file mode 100644
index 0000000..aca7c2b
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5RtreeBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment5RtreeBuilder extends AbstractSpatialIndexExperiment2Builder {
+
+    //SpatialIndexExperiment5XXX is exactly the same as SpatialIndexExperiment2XXX except queries are non-index only plan queries.
+    public SpatialIndexExperiment5RtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment5Rtree", config, "1node.xml", "base_1_ingest_query.aql", "1.dgen", false);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_rtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5ShbtreeBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5ShbtreeBuilder.java
new file mode 100644
index 0000000..2c066fd
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5ShbtreeBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment5ShbtreeBuilder extends AbstractSpatialIndexExperiment2Builder {
+
+    //SpatialIndexExperiment5XXX is exactly the same as SpatialIndexExperiment2XXX except queries are non-index only plan queries.
+    public SpatialIndexExperiment5ShbtreeBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment5Shbtree", config, "1node.xml", "base_1_ingest_query.aql", "1.dgen", false);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_shbtree.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5SifBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5SifBuilder.java
new file mode 100644
index 0000000..4ee4095
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/builder/SpatialIndexExperiment5SifBuilder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.asterix.experiment.builder;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLFileAction;
+import org.apache.asterix.experiment.client.LSMExperimentConstants;
+import org.apache.asterix.experiment.client.LSMExperimentSetRunner.LSMExperimentSetRunnerConfig;
+
+public class SpatialIndexExperiment5SifBuilder extends AbstractSpatialIndexExperiment2Builder {
+
+    //SpatialIndexExperiment5XXX is exactly the same as SpatialIndexExperiment2XXX except queries are non-index only plan queries.
+    public SpatialIndexExperiment5SifBuilder(LSMExperimentSetRunnerConfig config) {
+        super("SpatialIndexExperiment5Sif", config, "1node.xml", "base_1_ingest_query.aql", "1.dgen", false);
+    }
+
+    @Override
+    protected void doBuildDDL(SequentialActionList seq) {
+        seq.add(new RunAQLFileAction(httpClient, restHost, restPort, localExperimentRoot.resolve(
+                LSMExperimentConstants.AQL_DIR).resolve("spatial_1_sif.aql")));
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/LSMExperimentConstants.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/LSMExperimentConstants.java
new file mode 100644
index 0000000..c0e6440
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/LSMExperimentConstants.java
@@ -0,0 +1,37 @@
+/*
+ * 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.asterix.experiment.client;
+
+public class LSMExperimentConstants {
+
+    public static final String CONFIG_DIR = "configs";
+
+    public static final String AQL_DIR = "aql";
+
+    public static final String BASE_DIR = "base";
+
+    public static final String DGEN_DIR = "dgen";
+
+    public static final String LOG_DIR = "log";
+
+    public static final String BASE_TYPES = "base/base_types.aql";
+
+    public static final String ASTERIX_CONFIGURATION = "asterix-configuration.xml";
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/LSMExperimentSetRunner.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/LSMExperimentSetRunner.java
new file mode 100644
index 0000000..8b59449
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/LSMExperimentSetRunner.java
@@ -0,0 +1,381 @@
+/*
+ * 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.asterix.experiment.client;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.builder.AbstractExperimentBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1ADhbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1ADhvbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1ARtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1AShbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1ASifBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1BDhbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1BDhvbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1BRtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1BShbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1BSifBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1CDhbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1CDhvbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1CRtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1CShbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1CSifBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1DDhbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1DDhvbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1DRtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1DShbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment1DSifBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment2DhbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment2DhvbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment2RtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment2ShbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment2SifBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment3DhbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment3DhvbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment3PIdxLoadBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment3RtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment3ShbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment3SifBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment4DhbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment4DhvbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment4RtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment4ShbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment4SifBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment5DhbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment5DhvbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment5RtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment5ShbtreeBuilder;
+import org.apache.asterix.experiment.builder.SpatialIndexExperiment5SifBuilder;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.Option;
+
+public class LSMExperimentSetRunner {
+
+    private static final Logger LOGGER = Logger.getLogger(LSMExperimentSetRunner.class.getName());
+
+    public static class LSMExperimentSetRunnerConfig {
+
+        private final String logDirSuffix;
+
+        private final int nQueryRuns;
+
+        public LSMExperimentSetRunnerConfig(String logDirSuffix, int nQueryRuns) {
+            this.logDirSuffix = logDirSuffix;
+            this.nQueryRuns = nQueryRuns;
+        }
+
+        public String getLogDirSuffix() {
+            return logDirSuffix;
+        }
+
+        public int getNQueryRuns() {
+            return nQueryRuns;
+        }
+
+        @Option(name = "-rh", aliases = "--rest-host", usage = "Asterix REST API host address", required = true, metaVar = "HOST")
+        private String restHost;
+
+        public String getRESTHost() {
+            return restHost;
+        }
+
+        @Option(name = "-rp", aliases = "--rest-port", usage = "Asterix REST API port", required = true, metaVar = "PORT")
+        private int restPort;
+
+        public int getRESTPort() {
+            return restPort;
+        }
+
+        @Option(name = "-mh", aliases = "--managix-home", usage = "Path to MANAGIX_HOME directory", required = true, metaVar = "MGXHOME")
+        private String managixHome;
+
+        public String getManagixHome() {
+            return managixHome;
+        }
+
+        @Option(name = "-jh", aliases = "--java-home", usage = "Path to JAVA_HOME directory", required = true, metaVar = "JAVAHOME")
+        private String javaHome;
+
+        public String getJavaHome() {
+            return javaHome;
+        }
+
+        @Option(name = "-ler", aliases = "--local-experiment-root", usage = "Path to the local LSM experiment root directory", required = true, metaVar = "LOCALEXPROOT")
+        private String localExperimentRoot;
+
+        public String getLocalExperimentRoot() {
+            return localExperimentRoot;
+        }
+
+        @Option(name = "-u", aliases = "--username", usage = "Username to use for SSH/SCP", required = true, metaVar = "UNAME")
+        private String username;
+
+        public String getUsername() {
+            return username;
+        }
+
+        @Option(name = "-k", aliases = "--key", usage = "SSH key location", metaVar = "SSHKEY")
+        private String sshKeyLocation;
+
+        public String getSSHKeyLocation() {
+            return sshKeyLocation;
+        }
+
+        @Option(name = "-d", aliases = "--datagen-duartion", usage = "Data generation duration in seconds", metaVar = "DATAGENDURATION")
+        private int duration;
+
+        public int getDuration() {
+            return duration;
+        }
+
+        @Option(name = "-qd", aliases = "--querygen-duartion", usage = "Query generation duration in seconds", metaVar = "QUERYGENDURATION")
+        private int queryDuration;
+
+        public int getQueryDuration() {
+            return queryDuration;
+        }
+
+        @Option(name = "-regex", aliases = "--regex", usage = "Regular expression used to match experiment names", metaVar = "REGEXP")
+        private String regex;
+
+        public String getRegex() {
+            return regex;
+        }
+
+        @Option(name = "-oh", aliases = "--orchestrator-host", usage = "The host address of THIS orchestrator")
+        private String orchHost;
+
+        public String getOrchestratorHost() {
+            return orchHost;
+        }
+
+        @Option(name = "-op", aliases = "--orchestrator-port", usage = "The port to be used for the orchestrator server of THIS orchestrator")
+        private int orchPort;
+
+        public int getOrchestratorPort() {
+            return orchPort;
+        }
+
+        @Option(name = "-qoh", aliases = "--query-orchestrator-host", usage = "The host address of query orchestrator")
+        private String queryOrchHost;
+
+        public String getQueryOrchestratorHost() {
+            return queryOrchHost;
+        }
+
+        @Option(name = "-qop", aliases = "--query-orchestrator-port", usage = "The port to be used for the orchestrator server of query orchestrator")
+        private int queryOrchPort;
+
+        public int getQueryOrchestratorPort() {
+            return queryOrchPort;
+        }
+
+        @Option(name = "-di", aliases = "--data-interval", usage = " Initial data interval to use when generating data for exp 7")
+        private long dataInterval;
+
+        public long getDataInterval() {
+            return dataInterval;
+        }
+
+        @Option(name = "-ni", aliases = "--num-data-intervals", usage = "Number of data intervals to use when generating data for exp 7")
+        private int numIntervals;
+
+        public int getNIntervals() {
+            return numIntervals;
+        }
+
+        @Option(name = "-sf", aliases = "--stat-file", usage = "Enable IO/CPU stats and place in specified file")
+        private String statFile = null;
+
+        public String getStatFile() {
+            return statFile;
+        }
+
+        @Option(name = "-of", aliases = "--openstreetmap-filepath", usage = "The open street map gps point data file path")
+        private String openStreetMapFilePath;
+
+        public String getOpenStreetMapFilePath() {
+            return openStreetMapFilePath;
+        }
+
+        @Option(name = "-si", aliases = "--location-sample-interval", usage = "Location sample interval from open street map point data")
+        private int locationSampleInterval;
+
+        public int getLocationSampleInterval() {
+            return locationSampleInterval;
+        }
+
+        @Option(name = "-qsf", aliases = "--query-seed-filepath", usage = "The query seed file path")
+        private String querySeedFilePath;
+
+        public String getQuerySeedFilePath() {
+            return querySeedFilePath;
+        }
+
+        @Option(name = "-rcbi", aliases = "--record-count-per-batch-during-ingestion-only", usage = "Record count per batch during ingestion only")
+        private int recordCountPerBatchDuringIngestionOnly = 1000;
+
+        public int getRecordCountPerBatchDuringIngestionOnly() {
+            return recordCountPerBatchDuringIngestionOnly;
+        }
+
+        @Option(name = "-rcbq", aliases = "--record-count-per-batch-during-query", usage = "Record count per batch during query")
+        private int recordCountPerBatchDuringQuery = 1000;
+
+        public int getRecordCountPerBatchDuringQuery() {
+            return recordCountPerBatchDuringQuery;
+        }
+
+        @Option(name = "-dsti", aliases = "--data-gen-sleep-time-during-ingestion-only", usage = "DataGen sleep time in milliseconds after every recordCountPerBatchDuringIngestionOnly records were sent")
+        private long dataGenSleepTimeDuringIngestionOnly = 1;
+
+        public long getDataGenSleepTimeDuringIngestionOnly() {
+            return dataGenSleepTimeDuringIngestionOnly;
+        }
+
+        @Option(name = "-dstq", aliases = "--data-gen-sleep-time-during-query", usage = "DataGen sleep time in milliseconds after every recordCountPerBatchDuringQuery records were sent")
+        private long dataGenSleepTimeDuringQuery = 1;
+
+        public long getDataGenSleepTimeDuringQuery() {
+            return dataGenSleepTimeDuringQuery;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        //        LogManager.getRootLogger().setLevel(org.apache.log4j.Level.OFF);
+        LSMExperimentSetRunnerConfig config = new LSMExperimentSetRunnerConfig(String.valueOf(System
+                .currentTimeMillis()), 3);
+        CmdLineParser clp = new CmdLineParser(config);
+        try {
+            clp.parseArgument(args);
+        } catch (CmdLineException e) {
+            System.err.println(e.getMessage());
+            clp.printUsage(System.err);
+            System.exit(1);
+        }
+
+        Collection<AbstractExperimentBuilder> suite = new ArrayList<>();
+
+        suite.add(new SpatialIndexExperiment1ADhbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1ADhvbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1ARtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1AShbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1ASifBuilder(config));
+        suite.add(new SpatialIndexExperiment1BDhbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1BDhvbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1BRtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1BShbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1BSifBuilder(config));
+        suite.add(new SpatialIndexExperiment1CDhbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1CDhvbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1CRtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1CShbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1CSifBuilder(config));
+        suite.add(new SpatialIndexExperiment1DDhbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1DDhvbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1DRtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1DShbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment1DSifBuilder(config));
+        suite.add(new SpatialIndexExperiment2DhbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment2DhvbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment2RtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment2ShbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment2SifBuilder(config));
+        suite.add(new SpatialIndexExperiment3PIdxLoadBuilder(config));
+        suite.add(new SpatialIndexExperiment3DhbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment3DhvbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment3RtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment3ShbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment3SifBuilder(config));
+        suite.add(new SpatialIndexExperiment4DhbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment4DhvbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment4RtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment4ShbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment4SifBuilder(config));
+        suite.add(new SpatialIndexExperiment5DhbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment5DhvbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment5RtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment5ShbtreeBuilder(config));
+        suite.add(new SpatialIndexExperiment5SifBuilder(config));
+        //        suite.add(new Experiment7BBuilder(config));
+        //        suite.add(new Experiment7DBuilder(config));
+        //        suite.add(new Experiment7ABuilder(config));
+        //        suite.add(new Experiment8DBuilder(config));
+        //        suite.add(new Experiment8ABuilder(config));
+        //        suite.add(new Experiment8BBuilder(config));
+        //        suite.add(new Experiment9ABuilder(config));
+        //        suite.add(new Experiment9DBuilder(config));
+        //        suite.add(new Experiment9BBuilder(config));
+        //        suite.add(new Experiment6ABuilder(config));
+        //        suite.add(new Experiment6BBuilder(config));
+        //        suite.add(new Experiment6CBuilder(config));
+        //        suite.add(new Experiment2D1Builder(config));
+        //        suite.add(new Experiment2D2Builder(config));
+        //        suite.add(new Experiment2D4Builder(config));
+        //        suite.add(new Experiment2D8Builder(config));
+        //        suite.add(new Experiment2C1Builder(config));
+        //        suite.add(new Experiment2C2Builder(config));
+        //        suite.add(new Experiment2C4Builder(config));
+        //        suite.add(new Experiment2C8Builder(config));
+        //        suite.add(new Experiment2A1Builder(config));
+        //        suite.add(new Experiment2A2Builder(config));
+        //        suite.add(new Experiment2A4Builder(config));
+        //        suite.add(new Experiment2A8Builder(config));
+        //        suite.add(new Experiment2B1Builder(config));
+        //        suite.add(new Experiment2B2Builder(config));
+        //        suite.add(new Experiment2B4Builder(config));
+        //        suite.add(new Experiment2B8Builder(config));
+        //        suite.add(new Experiment1ABuilder(config));
+        //        suite.add(new Experiment1BBuilder(config));
+        //        suite.add(new Experiment1CBuilder(config));
+        //        suite.add(new Experiment1DBuilder(config));
+        //        suite.add(new Experiment4ABuilder(config));
+        //        suite.add(new Experiment4BBuilder(config));
+        //        suite.add(new Experiment4CBuilder(config));
+        //        suite.add(new Experiment4DBuilder(config));
+        //        suite.add(new Experiment3ABuilder(config));
+        //        suite.add(new Experiment3BBuilder(config));
+        //        suite.add(new Experiment3CBuilder(config));
+        //        suite.add(new Experiment3DBuilder(config));
+        //        suite.add(new Experiment5ABuilder(config));
+        //        suite.add(new Experiment5BBuilder(config));
+        //        suite.add(new Experiment5CBuilder(config));
+        //        suite.add(new Experiment5DBuilder(config));
+
+        Pattern p = config.getRegex() == null ? null : Pattern.compile(config.getRegex());
+
+        SequentialActionList exps = new SequentialActionList();
+        for (AbstractExperimentBuilder eb : suite) {
+            if (p == null || p.matcher(eb.getName()).matches()) {
+                exps.add(eb.build());
+                if (LOGGER.isLoggable(Level.INFO)) {
+                    LOGGER.info("Added " + eb.getName() + " to run list...");
+                }
+            }
+        }
+        exps.perform();
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/OrchestratorDGProtocol.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/OrchestratorDGProtocol.java
new file mode 100644
index 0000000..a29a74c
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/OrchestratorDGProtocol.java
@@ -0,0 +1,26 @@
+/*
+ * 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.asterix.experiment.client;
+
+public enum OrchestratorDGProtocol {
+    STOPPED,
+    RESUME,
+    REACHED
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/OrchestratorServer.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/OrchestratorServer.java
new file mode 100644
index 0000000..a69b0ce
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/OrchestratorServer.java
@@ -0,0 +1,158 @@
+/*
+ * 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.asterix.experiment.client;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.asterix.experiment.action.base.IAction;
+
+public class OrchestratorServer {
+
+    private static final Logger LOGGER = Logger.getLogger(OrchestratorServer.class.getName());
+
+    private final int port;
+
+    private final int nDataGens;
+
+    private final int nIntervals;
+
+    private final AtomicBoolean running;
+
+    private final IAction[] protocolActions;
+
+    private final boolean flagStopResume;
+
+    public OrchestratorServer(int port, int nDataGens, int nIntervals, IAction[] protocolActions) {
+        this.port = port;
+        this.nDataGens = nDataGens;
+        this.nIntervals = nIntervals;
+        running = new AtomicBoolean();
+        this.protocolActions = protocolActions;
+        this.flagStopResume = true;
+    }
+    
+    public synchronized void start() throws IOException, InterruptedException {
+        final AtomicBoolean bound = new AtomicBoolean();
+        running.set(true);
+        Thread t = new Thread(new Runnable() {
+
+            @Override
+            public void run() {
+                try {
+                    ServerSocket ss = new ServerSocket(port);
+                    synchronized (bound) {
+                        bound.set(true);
+                        bound.notifyAll();
+                    }
+                    Socket[] conn = new Socket[nDataGens];
+                    try {
+                        for (int i = 0; i < nDataGens; i++) {
+                            conn[i] = ss.accept();
+                        }
+                        for (int n = 0; n < nIntervals; ++n) {
+                            //TODO refactor operations according to the protocol message
+                            if (flagStopResume) {
+                                for (int i = 0; i < nDataGens; i++) {
+                                    receiveStopped(conn[i]);
+                                }
+                                protocolActions[n].perform();
+                                if (n != nIntervals - 1) {
+                                    for (int i = 0; i < nDataGens; i++) {
+                                        sendResume(conn[i]);
+                                    }
+                                }
+                            } else {
+                                for (int i = 0; i < nDataGens; i++) {
+                                    receiveReached(conn[i]);
+                                }
+                                protocolActions[n].perform();
+                            }
+                        }
+                    } finally {
+                        for (int i = 0; i < conn.length; ++i) {
+                            if (conn[i] != null) {
+                                conn[i].close();
+                            }
+                        }
+                        ss.close();
+                    }
+                    running.set(false);
+                    synchronized (OrchestratorServer.this) {
+                        OrchestratorServer.this.notifyAll();
+                    }
+                } catch (Throwable t) {
+                    t.printStackTrace();
+                }
+            }
+
+        });
+        t.start();
+        synchronized (bound) {
+            while (!bound.get()) {
+                bound.wait();
+            }
+        }
+    }
+
+    private void sendResume(Socket conn) throws IOException {
+        new DataOutputStream(conn.getOutputStream()).writeInt(OrchestratorDGProtocol.RESUME.ordinal());
+        conn.getOutputStream().flush();
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info("Sent " + OrchestratorDGProtocol.RESUME + " to " + conn.getRemoteSocketAddress());
+        }
+    }
+
+    private void receiveStopped(Socket conn) throws IOException {
+        int msg = new DataInputStream(conn.getInputStream()).readInt();
+        OrchestratorDGProtocol msgType = OrchestratorDGProtocol.values()[msg];
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info("Received " + msgType + " from " + conn.getRemoteSocketAddress());
+        }
+        if (msgType != OrchestratorDGProtocol.STOPPED) {
+            throw new IllegalStateException("Encounted unknown message type " + msgType);
+        }
+    }
+
+    private void receiveReached(Socket conn) throws IOException {
+        int msg = new DataInputStream(conn.getInputStream()).readInt();
+        OrchestratorDGProtocol msgType = OrchestratorDGProtocol.values()[msg];
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info("Received " + msgType + " from " + conn.getRemoteSocketAddress());
+        }
+        if (msgType != OrchestratorDGProtocol.REACHED) {
+            throw new IllegalStateException("Encounted unknown message type " + msgType);
+        }
+
+    }
+
+    public synchronized void awaitFinished() throws InterruptedException {
+        while (running.get()) {
+            wait();
+        }
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/OrchestratorServer7.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/OrchestratorServer7.java
new file mode 100644
index 0000000..c547393
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/OrchestratorServer7.java
@@ -0,0 +1,238 @@
+/*
+ * 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.asterix.experiment.client;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.asterix.experiment.action.base.IAction;
+import org.apache.asterix.experiment.builder.AbstractExperiment7Builder;
+
+public class OrchestratorServer7 {
+
+    private static final Logger LOGGER = Logger.getLogger(OrchestratorServer7.class.getName());
+
+    private final int port;
+
+    private final int nDataGens;
+
+    private final int nIntervals;
+
+    private final AtomicBoolean running;
+
+    private final IProtocolActionBuilder protoActionBuilder;
+    
+    private final IAction lsAction;
+
+    private static final int QUERY_TOTAL_COUNT = 2000;
+
+    public OrchestratorServer7(int port, int nDataGens, int nIntervals, IProtocolActionBuilder protoActionBuilder, IAction lsAction) {
+        this.port = port;
+        this.nDataGens = nDataGens;
+        this.nIntervals = nIntervals;
+        running = new AtomicBoolean();
+        this.protoActionBuilder = protoActionBuilder;
+        this.lsAction = lsAction;
+    }
+
+    public synchronized void start() throws IOException, InterruptedException {
+        final AtomicBoolean bound = new AtomicBoolean();
+        running.set(true);
+        Thread t = new Thread(new Runnable() {
+
+            @Override
+            public void run() {
+                try {
+                    ServerSocket ss = new ServerSocket(port);
+                    synchronized (bound) {
+                        bound.set(true);
+                        bound.notifyAll();
+                    }
+                    Socket[] conn = new Socket[nDataGens];
+                    try {
+                        for (int i = 0; i < nDataGens; i++) {
+                            conn[i] = ss.accept();
+                        }
+                        AtomicInteger round = new AtomicInteger();
+                        AtomicBoolean done = new AtomicBoolean(false);
+                        Thread pct = new Thread(new ProtocolConsumer(conn, nIntervals, round, done));
+                        pct.start();
+                        int[] queryType = new int[] { 10, 100, 1000, 10000 };
+                        int type = 0;
+                        //step1. send query when it reaches the query begin round
+                        if (LOGGER.isLoggable(Level.INFO)) {
+                            LOGGER.info("Step1 starts");
+                        }
+                        boolean sendQuery = false;
+                        while (!done.get()) {
+                            if (!sendQuery) {
+                                synchronized (round) {
+                                    while (true) {
+                                        if (round.get() >= AbstractExperiment7Builder.QUERY_BEGIN_ROUND) {
+                                            sendQuery = true;
+                                            break;
+                                        }
+                                        round.wait();
+                                    }
+                                }
+                            }
+                            if (sendQuery) {
+                                protoActionBuilder.buildQueryAction(queryType[type % 4], false).perform();
+                                type = (++type) % 4;
+                            }
+
+                        }
+                        pct.join();
+                        if (LOGGER.isLoggable(Level.INFO)) {
+                            LOGGER.info("Step1 ends");
+                        }
+                        
+                        if (LOGGER.isLoggable(Level.INFO)) {
+                            LOGGER.info("Step2 starts");
+                        }
+                        //step2. send one more round of queries after ingestion is over
+                        protoActionBuilder.buildIOWaitAction().perform();
+                        lsAction.perform();
+                        for (int i = 0; i < QUERY_TOTAL_COUNT; i++) {
+                            protoActionBuilder.buildQueryAction(queryType[i % 4], true).perform();
+                        }
+                        if (LOGGER.isLoggable(Level.INFO)) {
+                            LOGGER.info("Step2 ends");
+                        }
+                        
+                        if (LOGGER.isLoggable(Level.INFO)) {
+                            LOGGER.info("Step3 starts");
+                        }
+                        //step3. compact dataset
+                        protoActionBuilder.buildCompactAction().perform();
+                        protoActionBuilder.buildIOWaitAction().perform();
+                        if (LOGGER.isLoggable(Level.INFO)) {
+                            LOGGER.info("Step3 ends");
+                        }
+                        
+                        if (LOGGER.isLoggable(Level.INFO)) {
+                            LOGGER.info("Step4 starts");
+                        }
+                        //step4. send last round of queries after the compaction is over
+                        for (int i = 0; i < QUERY_TOTAL_COUNT; i++) {
+                            protoActionBuilder.buildQueryAction(queryType[i % 4], true).perform();
+                        }
+                        if (LOGGER.isLoggable(Level.INFO)) {
+                            LOGGER.info("Step4 ends");
+                        }
+
+                    } finally {
+                        for (int i = 0; i < conn.length; ++i) {
+                            if (conn[i] != null) {
+                                conn[i].close();
+                            }
+                        }
+                        ss.close();
+                    }
+                    running.set(false);
+                    synchronized (OrchestratorServer7.this) {
+                        OrchestratorServer7.this.notifyAll();
+                    }
+                } catch (Throwable t) {
+                    t.printStackTrace();
+                }
+            }
+
+        });
+        t.start();
+        synchronized (bound) {
+            while (!bound.get()) {
+                bound.wait();
+            }
+        }
+    }
+
+    private static class ProtocolConsumer implements Runnable {
+
+        private final Socket[] conn;
+
+        private final int nIntervals;
+
+        private final AtomicInteger interval;
+
+        private final AtomicBoolean done;
+
+        public ProtocolConsumer(Socket[] conn, int nIntervals, AtomicInteger interval, AtomicBoolean done) {
+            this.conn = conn;
+            this.nIntervals = nIntervals;
+            this.interval = interval;
+            this.done = done;
+        }
+
+        @Override
+        public void run() {
+            interval.set(0);
+            try {
+                for (int n = 0; n < nIntervals; ++n) {
+                    for (int i = 0; i < conn.length; i++) {
+                        receiveReached(conn[i]);
+                    }
+                    synchronized (interval) {
+                        interval.getAndIncrement();
+                        interval.notifyAll();
+                    }
+                }
+                done.set(true);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+    }
+
+    private static void receiveReached(Socket conn) throws IOException {
+        int msg = new DataInputStream(conn.getInputStream()).readInt();
+        OrchestratorDGProtocol msgType = OrchestratorDGProtocol.values()[msg];
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info("Received " + msgType + " from " + conn.getRemoteSocketAddress());
+        }
+        if (msgType != OrchestratorDGProtocol.REACHED) {
+            throw new IllegalStateException("Encounted unknown message type " + msgType);
+        }
+
+    }
+
+    public synchronized void awaitFinished() throws InterruptedException {
+        while (running.get()) {
+            wait();
+        }
+    }
+
+    public interface IProtocolActionBuilder {
+        public IAction buildQueryAction(long cardinality, boolean finalRound) throws Exception;
+
+        public IAction buildIOWaitAction() throws Exception;
+
+        public IAction buildCompactAction() throws Exception;
+
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/OrchestratorServer9.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/OrchestratorServer9.java
new file mode 100644
index 0000000..be50e7c
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/OrchestratorServer9.java
@@ -0,0 +1,164 @@
+/*
+ * 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.asterix.experiment.client;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.asterix.experiment.action.base.IAction;
+
+public class OrchestratorServer9 {
+
+    private static final Logger LOGGER = Logger.getLogger(OrchestratorServer9.class.getName());
+
+    private final int port;
+
+    private final int nDataGens;
+
+    private final int nIntervals;
+
+    private final AtomicBoolean running;
+
+    private final IProtocolActionBuilder protoActionBuilder;
+
+    public OrchestratorServer9(int port, int nDataGens, int nIntervals, IProtocolActionBuilder protoActionBuilder) {
+        this.port = port;
+        this.nDataGens = nDataGens;
+        this.nIntervals = nIntervals;
+        running = new AtomicBoolean();
+        this.protoActionBuilder = protoActionBuilder;
+    }
+
+    public synchronized void start() throws IOException, InterruptedException {
+        final AtomicBoolean bound = new AtomicBoolean();
+        running.set(true);
+        Thread t = new Thread(new Runnable() {
+
+            @Override
+            public void run() {
+                try {
+                    ServerSocket ss = new ServerSocket(port);
+                    synchronized (bound) {
+                        bound.set(true);
+                        bound.notifyAll();
+                    }
+                    Socket[] conn = new Socket[nDataGens];
+                    try {
+                        for (int i = 0; i < nDataGens; i++) {
+                            conn[i] = ss.accept();
+                        }
+                        AtomicInteger round = new AtomicInteger();
+                        AtomicBoolean done = new AtomicBoolean(false);
+                        Thread pct = new Thread(new ProtocolConsumer(conn, nIntervals, round, done));
+                        pct.start();
+                        while (!done.get()) {
+                            protoActionBuilder.buildAction(round.get()).perform();
+                        }
+                        pct.join();
+                    } finally {
+                        for (int i = 0; i < conn.length; ++i) {
+                            if (conn[i] != null) {
+                                conn[i].close();
+                            }
+                        }
+                        ss.close();
+                    }
+                    running.set(false);
+                    synchronized (OrchestratorServer9.this) {
+                        OrchestratorServer9.this.notifyAll();
+                    }
+                } catch (Throwable t) {
+                    t.printStackTrace();
+                }
+            }
+
+        });
+        t.start();
+        synchronized (bound) {
+            while (!bound.get()) {
+                bound.wait();
+            }
+        }
+    }
+
+    private static class ProtocolConsumer implements Runnable {
+
+        private final Socket[] conn;
+
+        private final int nIntervals;
+
+        private final AtomicInteger interval;
+
+        private final AtomicBoolean done;
+
+        public ProtocolConsumer(Socket[] conn, int nIntervals, AtomicInteger interval, AtomicBoolean done) {
+            this.conn = conn;
+            this.nIntervals = nIntervals;
+            this.interval = interval;
+            this.done = done;
+        }
+
+        @Override
+        public void run() {
+            interval.set(0);
+            try {
+                for (int n = 0; n < nIntervals; ++n) {
+                    for (int i = 0; i < conn.length; i++) {
+                        receiveReached(conn[i]);
+                    }
+                    interval.getAndIncrement();
+                }
+                done.set(true);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+    }
+
+    private static void receiveReached(Socket conn) throws IOException {
+        int msg = new DataInputStream(conn.getInputStream()).readInt();
+        OrchestratorDGProtocol msgType = OrchestratorDGProtocol.values()[msg];
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info("Received " + msgType + " from " + conn.getRemoteSocketAddress());
+        }
+        if (msgType != OrchestratorDGProtocol.REACHED) {
+            throw new IllegalStateException("Encounted unknown message type " + msgType);
+        }
+
+    }
+
+    public synchronized void awaitFinished() throws InterruptedException {
+        while (running.get()) {
+            wait();
+        }
+    }
+
+    public interface IProtocolActionBuilder {
+        public IAction buildAction(int round) throws Exception;
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/RecordCountingServer.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/RecordCountingServer.java
new file mode 100644
index 0000000..22e5ac0
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/RecordCountingServer.java
@@ -0,0 +1,166 @@
+/*
+ * 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.asterix.experiment.client;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class RecordCountingServer {
+
+    private final ExecutorService threadPool;
+
+    private final int port;
+
+    private final long duration;
+
+    private ServerSocket ss;
+
+    private boolean stopped;
+
+    private final Object o = new Object();
+
+    final AtomicBoolean b = new AtomicBoolean(false);
+
+    public RecordCountingServer(int port, long duration) {
+        this.port = port;
+        this.duration = duration;
+        threadPool = Executors.newCachedThreadPool();
+    }
+
+    public void start() throws IOException, InterruptedException {
+        Thread t = new Thread(new Runnable() {
+
+            @Override
+            public void run() {
+                try {
+                    stopped = false;
+                    ss = new ServerSocket(port);
+                    while (true) {
+                        Socket s = ss.accept();
+                        if (stopped) {
+                            break;
+                        }
+                        threadPool.execute(new RecordCountingThread(s, duration));
+                        synchronized (o) {
+                            b.set(true);
+                            o.notifyAll();
+                        }
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+        t.start();
+    }
+
+    public void awaitFirstConnection() throws InterruptedException {
+        synchronized (o) {
+            if (!b.get()) {
+                o.wait();
+            }
+        }
+    }
+
+    public void stop() throws IOException, InterruptedException {
+        stopped = true;
+        threadPool.shutdown();
+        threadPool.awaitTermination(1000, TimeUnit.DAYS);
+        ss.close();
+    }
+
+    private static class RecordCountingThread implements Runnable {
+        private final Socket s;
+
+        private final long duration;
+
+        private final char[] buf;
+
+        private int index;
+
+        private int count;
+
+        public RecordCountingThread(Socket s, long duration) {
+            this.s = s;
+            this.duration = duration;
+            buf = new char[32 * 1024];
+        }
+
+        @Override
+        public void run() {
+            count = 0;
+            index = 0;
+            long start = System.currentTimeMillis();
+            try {
+                InputStreamReader r = new InputStreamReader(s.getInputStream());
+                while (System.currentTimeMillis() - start < duration) {
+                    fill(r);
+                    countRecords();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            long end = System.currentTimeMillis();
+            System.out.println("Read " + count + " records in " + (end - start) / 1000 + " seconds");
+        }
+
+        private void countRecords() {
+            for (int i = 0; i < index; ++i) {
+                if (buf[i] == '\n') {
+                    ++count;
+                }
+            }
+        }
+
+        private void fill(Reader r) throws IOException {
+            index = 0;
+            int read = r.read(buf);
+            if (read == -1) {
+                index = 0;
+                return;
+            }
+            index += read;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        long duration = Long.parseLong(args[0]);
+        int port1 = Integer.parseInt(args[1]);
+        int port2 = Integer.parseInt(args[2]);
+        RecordCountingServer rcs1 = new RecordCountingServer(port1, duration * 1000);
+        RecordCountingServer rcs2 = new RecordCountingServer(port2, duration * 1000);
+        try {
+            rcs1.start();
+            rcs2.start();
+            rcs1.awaitFirstConnection();
+            rcs2.awaitFirstConnection();
+        } finally {
+            rcs1.stop();
+            rcs2.stop();
+        }
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SocketDataGeneratorExecutable.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SocketDataGeneratorExecutable.java
new file mode 100644
index 0000000..eeac0b4
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SocketDataGeneratorExecutable.java
@@ -0,0 +1,57 @@
+/*
+ * 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.asterix.experiment.client;
+
+import java.net.Socket;
+import java.util.Collections;
+
+import org.apache.asterix.experiment.action.base.AbstractAction;
+import org.apache.asterix.tools.external.data.TweetGeneratorForSpatialIndexEvaluation;
+
+public class SocketDataGeneratorExecutable extends AbstractAction {
+
+    private final String adapterHost;
+
+    private final int adapterPort;
+
+    public SocketDataGeneratorExecutable(String adapterHost, int adapterPort) {
+        this.adapterHost = adapterHost;
+        this.adapterPort = adapterPort;
+    }
+
+    @Override
+    protected void doPerform() throws Exception {
+        Thread.sleep(4000);
+        Socket s = new Socket(adapterHost, adapterPort);
+        try {
+            TweetGeneratorForSpatialIndexEvaluation tg = new TweetGeneratorForSpatialIndexEvaluation(Collections.<String, String> emptyMap(), 0,
+                    TweetGeneratorForSpatialIndexEvaluation.OUTPUT_FORMAT_ADM_STRING, s.getOutputStream());
+            long start = System.currentTimeMillis();
+            while (tg.setNextRecordBatch(1000)) {
+            }
+            long end = System.currentTimeMillis();
+            long total = end - start;
+            System.out.println("Generation finished: " + tg.getNumFlushedTweets() + " in " + total / 1000 + " seconds");
+        } finally {
+            s.close();
+        }
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SocketTweetGenerator.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SocketTweetGenerator.java
new file mode 100644
index 0000000..f817fc9
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SocketTweetGenerator.java
@@ -0,0 +1,389 @@
+/*
+ * 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.asterix.experiment.client;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.asterix.tools.external.data.TweetGeneratorForSpatialIndexEvaluation;
+import org.apache.commons.lang3.tuple.Pair;
+
+public class SocketTweetGenerator {
+
+    private final ExecutorService threadPool;
+
+    private final int partitionRangeStart;
+
+    private final int dataGenDuration;
+
+    private final int queryGenDuration;
+
+    private final long startDataInterval;
+
+    private final int nDataIntervals;
+
+    private final String orchHost;
+
+    private final int orchPort;
+
+    private final List<Pair<String, Integer>> receiverAddresses;
+
+    private final String openStreetMapFilePath;
+    private final int locationSampleInterval;
+    private final int recordCountPerBatchDuringIngestionOnly;
+    private final int recordCountPerBatchDuringQuery;
+    private final long dataGenSleepTimeDuringIngestionOnly;
+    private final long dataGenSleepTimeDuringQuery;
+
+    private final Mode mode;
+
+    private enum Mode {
+        TIME,
+        DATA
+    }
+
+    public SocketTweetGenerator(SocketTweetGeneratorConfig config) {
+        threadPool = Executors.newCachedThreadPool(new ThreadFactory() {
+
+            private final AtomicInteger count = new AtomicInteger();
+
+            @Override
+            public Thread newThread(Runnable r) {
+                int tid = count.getAndIncrement();
+                Thread t = new Thread(r, "DataGeneratorThread: " + tid);
+                t.setDaemon(true);
+                return t;
+            }
+        });
+
+        partitionRangeStart = config.getPartitionRangeStart();
+        dataGenDuration = config.getDataGenDuration();
+        queryGenDuration = config.getQueryGenDuration();
+        startDataInterval = config.getDataInterval();
+        nDataIntervals = config.getNIntervals();
+        orchHost = config.getOrchestratorHost();
+        orchPort = config.getOrchestratorPort();
+        receiverAddresses = config.getAddresses();
+        mode = startDataInterval > 0 ? Mode.DATA : Mode.TIME;
+        openStreetMapFilePath = config.getOpenStreetMapFilePath();
+        locationSampleInterval = config.getLocationSampleInterval();
+        recordCountPerBatchDuringIngestionOnly = config.getRecordCountPerBatchDuringIngestionOnly();
+        recordCountPerBatchDuringQuery = config.getRecordCountPerBatchDuringQuery();
+        dataGenSleepTimeDuringIngestionOnly = config.getDataGenSleepTimeDuringIngestionOnly();
+        dataGenSleepTimeDuringQuery = config.getDataGenSleepTimeDuringQuery();
+    }
+
+    public void start() throws Exception {
+        final Semaphore sem = new Semaphore((receiverAddresses.size() - 1) * -1);
+        int i = 0;
+        for (Pair<String, Integer> address : receiverAddresses) {
+            threadPool.submit(new DataGenerator(mode, sem, address.getLeft(), address.getRight(), i
+                    + partitionRangeStart, dataGenDuration, queryGenDuration, nDataIntervals, startDataInterval,
+                    orchHost, orchPort, openStreetMapFilePath, locationSampleInterval,
+                    recordCountPerBatchDuringIngestionOnly, recordCountPerBatchDuringQuery,
+                    dataGenSleepTimeDuringIngestionOnly, dataGenSleepTimeDuringQuery));
+            ++i;
+        }
+        sem.acquire();
+    }
+
+    public static class DataGenerator implements Runnable {
+
+        private static final Logger LOGGER = Logger.getLogger(DataGenerator.class.getName());
+
+        private final Mode m;
+        private final Semaphore sem;
+        private final String host;
+        private final int port;
+        private final int partition;
+        private final int dataGenDuration;
+        private final int queryGenDuration;
+        private final int nDataIntervals;
+        private final String orchHost;
+        private final int orchPort;
+
+        private int currentInterval;
+        private long nextStopInterval;
+        private final long dataSizeInterval;
+        private final boolean flagStopResume;
+        private final String openStreetMapFilePath;
+        private final int locationSampleInterval;
+        private final int recordCountPerBatchDuringIngestionOnly;
+        private final int recordCountPerBatchDuringQuery;
+        private final long dataGenSleepTimeDuringIngestionOnly;
+        private final long dataGenSleepTimeDuringQuery;
+
+        public DataGenerator(Mode m, Semaphore sem, String host, int port, int partition, int dataGenDuration,
+                int queryGenDuration, int nDataIntervals, long dataSizeInterval, String orchHost, int orchPort,
+                String openStreetMapFilePath, int locationSampleInterval, int recordCountPerBatchDuringIngestionOnly,
+                int recordCountPerBatchDuringQuery, long dataGenSleepTimeDuringIngestionOnly,
+                long dataGenSleepTimeDuringQuery) {
+            this.m = m;
+            this.sem = sem;
+            this.host = host;
+            this.port = port;
+            this.partition = partition;
+            this.dataGenDuration = dataGenDuration;
+            this.queryGenDuration = queryGenDuration;
+            this.nDataIntervals = nDataIntervals;
+            currentInterval = 0;
+            this.dataSizeInterval = dataSizeInterval;
+            this.nextStopInterval = dataSizeInterval;
+            this.orchHost = orchHost;
+            this.orchPort = orchPort;
+            this.flagStopResume = false;
+            this.openStreetMapFilePath = openStreetMapFilePath;
+            //simple heuristic to generate different data from different data generator.
+            int lsi = locationSampleInterval + (partition + 1) * (partition <= 4 ? 7 : 9);
+            this.locationSampleInterval = lsi;
+            this.recordCountPerBatchDuringIngestionOnly = recordCountPerBatchDuringIngestionOnly;
+            this.recordCountPerBatchDuringQuery = recordCountPerBatchDuringQuery;
+            this.dataGenSleepTimeDuringIngestionOnly = dataGenSleepTimeDuringIngestionOnly;
+            this.dataGenSleepTimeDuringQuery = dataGenSleepTimeDuringQuery;
+        }
+
+        @Override
+        public void run() {
+            LOGGER.info("\nDataGen[" + partition + "] running with the following parameters: \n" + "dataGenDuration : "
+                    + dataGenDuration + "\n" + "queryGenDuration : " + queryGenDuration + "\n" + "nDataIntervals : "
+                    + nDataIntervals + "\n" + "dataSizeInterval : " + dataSizeInterval + "\n"
+                    + "recordCountPerBatchDuringIngestionOnly : " + recordCountPerBatchDuringIngestionOnly + "\n"
+                    + "recordCountPerBatchDuringQuery : " + recordCountPerBatchDuringQuery + "\n"
+                    + "dataGenSleepTimeDuringIngestionOnly : " + dataGenSleepTimeDuringIngestionOnly + "\n"
+                    + "dataGenSleepTimeDuringQuery : " + dataGenSleepTimeDuringQuery + "\n"
+                    + "locationSampleInterval : " + locationSampleInterval);
+
+            try {
+                Socket s = new Socket(host, port);
+                try {
+                    Socket orchSocket = null;
+                    if (m == Mode.DATA && orchHost != null) {
+                        orchSocket = new Socket(orchHost, orchPort);
+                    }
+                    TweetGeneratorForSpatialIndexEvaluation tg = null;
+                    try {
+                        Map<String, String> config = new HashMap<>();
+                        String durationVal = m == Mode.TIME ? String.valueOf(dataGenDuration) : "0";
+                        config.put(TweetGeneratorForSpatialIndexEvaluation.KEY_DURATION, String.valueOf(durationVal));
+                        if (openStreetMapFilePath != null) {
+                            config.put(TweetGeneratorForSpatialIndexEvaluation.KEY_OPENSTREETMAP_FILEPATH,
+                                    openStreetMapFilePath);
+                            config.put(TweetGeneratorForSpatialIndexEvaluation.KEY_LOCATION_SAMPLE_INTERVAL,
+                                    String.valueOf(locationSampleInterval));
+                        }
+                        tg = new TweetGeneratorForSpatialIndexEvaluation(config, partition,
+                                TweetGeneratorForSpatialIndexEvaluation.OUTPUT_FORMAT_ADM_STRING, s.getOutputStream());
+                        long startTS = System.currentTimeMillis();
+                        long prevTS = startTS;
+                        long curTS = startTS;
+                        int round = 0;
+                        while (tg.setNextRecordBatch(recordCountPerBatchDuringIngestionOnly)) {
+                            if (m == Mode.DATA) {
+                                if (tg.getNumFlushedTweets() >= nextStopInterval) {
+                                    //TODO stop/resume option
+                                    if (orchSocket != null) {
+                                        if (flagStopResume) {
+                                            // send stop to orchestrator
+                                            sendStopped(orchSocket);
+                                        } else {
+                                            sendReached(orchSocket);
+                                        }
+                                    }
+
+                                    // update intervals
+                                    // TODO give options: exponential/linear interval
+                                    nextStopInterval += dataSizeInterval;
+                                    if (++currentInterval >= nDataIntervals) {
+                                        break;
+                                    }
+
+                                    if (orchSocket != null) {
+                                        if (flagStopResume) {
+                                            receiveResume(orchSocket);
+                                        }
+                                    }
+                                }
+                            }
+                            curTS = System.currentTimeMillis();
+                            if (LOGGER.isLoggable(Level.INFO)) {
+                                round++;
+                                if ((round * recordCountPerBatchDuringIngestionOnly) % 100000 == 0) {
+                                    System.out.println("DataGen[" + partition
+                                            + "][During ingestion only][TimeToInsert100000] " + (curTS - prevTS)
+                                            + " in milliseconds");
+                                    round = 0;
+                                    prevTS = curTS;
+                                }
+                            }
+                            //to prevent congestion in feed pipe line. 
+                            if (dataGenSleepTimeDuringIngestionOnly > 0) {
+                                Thread.sleep(dataGenSleepTimeDuringIngestionOnly);
+                            }
+                        }
+
+                        if (LOGGER.isLoggable(Level.INFO)) {
+                            LOGGER.info("DataGen[" + partition
+                                    + "][During ingestion only][InsertCount] Num tweets flushed = "
+                                    + tg.getNumFlushedTweets() + " in "
+                                    + ((System.currentTimeMillis() - startTS) / 1000) + " seconds from "
+                                    + InetAddress.getLocalHost() + " to " + host + ":" + port);
+                        }
+
+                        if (orchSocket != null && queryGenDuration > 0) {
+                            //wait until orchestrator server's resume message is received.
+                            receiveResume(orchSocket);
+
+                            //reset duration and flushed tweet count
+                            tg.resetDurationAndFlushedTweetCount(queryGenDuration);
+
+                            prevTS = System.currentTimeMillis();
+                            round = 0;
+                            //start sending record
+                            while (tg.setNextRecordBatch(recordCountPerBatchDuringQuery)) {
+                                curTS = System.currentTimeMillis();
+                                if (LOGGER.isLoggable(Level.INFO)) {
+                                    round++;
+                                    if ((round * recordCountPerBatchDuringQuery) % 100000 == 0) {
+                                        System.out.println("DataGen[" + partition
+                                                + "][During ingestion + queries][TimeToInsert100000] "
+                                                + (curTS - prevTS) + " in milliseconds");
+                                        round = 0;
+                                        prevTS = curTS;
+                                    }
+                                }
+                                if (dataGenSleepTimeDuringQuery > 0) {
+                                    Thread.sleep(dataGenSleepTimeDuringQuery);
+                                }
+                            }
+                            if (LOGGER.isLoggable(Level.INFO)) {
+                                LOGGER.info("DataGen[" + partition
+                                        + "][During ingestion + queries][InsertCount] Num tweets flushed = "
+                                        + tg.getNumFlushedTweets() + " in " + queryGenDuration + " seconds from "
+                                        + InetAddress.getLocalHost() + " to " + host + ":" + port);
+                            }
+                            //send reached message to orchestrator server
+                            sendReached(orchSocket);
+                        }
+
+                    } finally {
+                        if (orchSocket != null) {
+                            orchSocket.close();
+                        }
+                        if (LOGGER.isLoggable(Level.INFO)) {
+                            LOGGER.info("Num tweets flushed = " + tg.getNumFlushedTweets() + " in " + dataGenDuration
+                                    + " seconds from " + InetAddress.getLocalHost() + " to " + host + ":" + port);
+                        }
+                    }
+                } catch (Throwable t) {
+                    t.printStackTrace();
+                } finally {
+                    s.close();
+                }
+            } catch (Throwable t) {
+                System.err.println("Error connecting to " + host + ":" + port);
+                t.printStackTrace();
+            } finally {
+                sem.release();
+            }
+        }
+
+        private void sendReached(Socket s) throws IOException {
+            new DataOutputStream(s.getOutputStream()).writeInt(OrchestratorDGProtocol.REACHED.ordinal());
+            s.getOutputStream().flush();
+            if (LOGGER.isLoggable(Level.INFO)) {
+                LOGGER.info("Sent " + OrchestratorDGProtocol.REACHED + " to " + s.getRemoteSocketAddress());
+            }
+        }
+
+        private void receiveResume(Socket s) throws IOException {
+            int msg = new DataInputStream(s.getInputStream()).readInt();
+            OrchestratorDGProtocol msgType = OrchestratorDGProtocol.values()[msg];
+            if (LOGGER.isLoggable(Level.INFO)) {
+                LOGGER.info("Received " + msgType + " from " + s.getRemoteSocketAddress());
+            }
+            if (msgType != OrchestratorDGProtocol.RESUME) {
+                throw new IllegalStateException("Unknown protocol message received: " + msgType);
+            }
+        }
+
+        private void sendStopped(Socket s) throws IOException {
+            new DataOutputStream(s.getOutputStream()).writeInt(OrchestratorDGProtocol.STOPPED.ordinal());
+            s.getOutputStream().flush();
+            if (LOGGER.isLoggable(Level.INFO)) {
+                LOGGER.info("Sent " + OrchestratorDGProtocol.STOPPED + " to " + s.getRemoteSocketAddress());
+            }
+        }
+
+    }
+
+    private static class CircularByteArrayOutputStream extends OutputStream {
+
+        private final byte[] buf;
+
+        private int index;
+
+        public CircularByteArrayOutputStream() {
+            buf = new byte[32 * 1024];
+            index = 0;
+        }
+
+        @Override
+        public void write(byte b[], int off, int len) throws IOException {
+            if (b == null) {
+                throw new NullPointerException();
+            } else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) {
+                throw new IndexOutOfBoundsException();
+            } else if (len == 0) {
+                return;
+            }
+
+            int remain = len;
+            int remainOff = off;
+            while (remain > 0) {
+                int avail = buf.length - index;
+                System.arraycopy(b, remainOff, buf, index, avail);
+                remainOff += avail;
+                remain -= avail;
+                index = (index + avail) % buf.length;
+            }
+        }
+
+        @Override
+        public void write(int b) throws IOException {
+            buf[index] = (byte) b;
+            index = (index + 1) % buf.length;
+        }
+
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SocketTweetGeneratorConfig.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SocketTweetGeneratorConfig.java
new file mode 100644
index 0000000..d3bb4bd
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SocketTweetGeneratorConfig.java
@@ -0,0 +1,173 @@
+/*
+ * 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.asterix.experiment.client;
+
+import java.util.List;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.Option;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.OptionHandler;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
+
+public class SocketTweetGeneratorConfig {
+
+    @Option(name = "-p", aliases = "--partition-range-start", usage = "Starting partition number for the set of data generators (default = 0)")
+    private int partitionRangeStart = 0;
+
+    public int getPartitionRangeStart() {
+        return partitionRangeStart;
+    }
+
+    @Option(name = "-d", aliases = { "--datagen-duration" }, usage = "Duration in seconds to run data generation")
+    private int duration = -1;
+
+    public int getDataGenDuration() {
+        return duration;
+    }
+
+    @Option(name = "-qd", aliases = { "--querygen-duration" }, usage = "Duration in seconds to run query generation")
+    private int queryDuration = -1;
+
+    public int getQueryGenDuration() {
+        return queryDuration;
+    }
+
+    @Option(name = "-di", aliases = "--data-interval", usage = "Initial data interval to use when generating data based on data size")
+    private long dataInterval = -1;
+
+    public long getDataInterval() {
+        return dataInterval;
+    }
+
+    @Option(name = "-ni", aliases = "--num-intervals", usage = "Number of intervals to use when generating data based on data size (default = 4)")
+    private int nIntervals = 4;
+
+    public int getNIntervals() {
+        return nIntervals;
+    }
+
+    @Option(name = "-oh", aliases = "--orachestrator-host", usage = "The host name of the orchestrator")
+    private String orchHost;
+
+    public String getOrchestratorHost() {
+        return orchHost;
+    }
+
+    @Option(name = "-op", aliases = "--orchestrator-port", usage = "The port number of the orchestrator")
+    private int orchPort;
+
+    public int getOrchestratorPort() {
+        return orchPort;
+    }
+
+    @Option(name = "-of", aliases = "--openstreetmap-filepath", usage = "The open street map gps point data file path")
+    private String openStreetMapFilePath;
+
+    public String getOpenStreetMapFilePath() {
+        return openStreetMapFilePath;
+    }
+
+    @Option(name = "-si", aliases = "--location-sample-interval", usage = "Location sample interval from open street map point data")
+    private int locationSampleInterval;
+
+    public int getLocationSampleInterval() {
+        return locationSampleInterval;
+    }
+
+    @Option(name = "-rcbi", aliases = "--record-count-per-batch-during-ingestion-only", usage = "Record count per batch during ingestion only")
+    private int recordCountPerBatchDuringIngestionOnly = 1000;
+
+    public int getRecordCountPerBatchDuringIngestionOnly() {
+        return recordCountPerBatchDuringIngestionOnly;
+    }
+
+    @Option(name = "-rcbq", aliases = "--record-count-per-batch-during-query", usage = "Record count per batch during query")
+    private int recordCountPerBatchDuringQuery = 1000;
+
+    public int getRecordCountPerBatchDuringQuery() {
+        return recordCountPerBatchDuringQuery;
+    }
+
+    @Option(name = "-dsti", aliases = "--data-gen-sleep-time-during-ingestion-only", usage = "DataGen sleep time in milliseconds after every recordCountPerBatchDuringIngestionOnly records were sent")
+    private long dataGenSleepTimeDuringIngestionOnly = 1;
+
+    public long getDataGenSleepTimeDuringIngestionOnly() {
+        return dataGenSleepTimeDuringIngestionOnly;
+    }
+
+    @Option(name = "-dstq", aliases = "--data-gen-sleep-time-during-query", usage = "DataGen sleep time in milliseconds after every recordCountPerBatchDuringQuery records were sent")
+    private long dataGenSleepTimeDuringQuery = 1;
+
+    public long getDataGenSleepTimeDuringQuery() {
+        return dataGenSleepTimeDuringQuery;
+    }
+
+    @Argument(required = true, usage = "A list of <ip>:<port> pairs (addresses) to send data to", metaVar = "addresses...", handler = AddressOptionHandler.class)
+    private List<Pair<String, Integer>> addresses;
+
+    public List<Pair<String, Integer>> getAddresses() {
+        return addresses;
+    }
+
+    public static class AddressOptionHandler extends OptionHandler<Pair<String, Integer>> {
+
+        public AddressOptionHandler(CmdLineParser parser, OptionDef option, Setter<? super Pair<String, Integer>> setter) {
+            super(parser, option, setter);
+        }
+
+        @Override
+        public int parseArguments(Parameters params) throws CmdLineException {
+            int counter = 0;
+            while (true) {
+                String param;
+                try {
+                    param = params.getParameter(counter);
+                } catch (CmdLineException ex) {
+                    break;
+                }
+
+                String[] hostPort = param.split(":");
+                if (hostPort.length != 2) {
+                    throw new CmdLineException("Invalid address: " + param + ". Expected <host>:<port>");
+                }
+                Integer port = null;
+                try {
+                    port = Integer.parseInt(hostPort[1]);
+                } catch (NumberFormatException e) {
+                    throw new CmdLineException("Invalid port " + hostPort[1] + " for address " + param + ".");
+                }
+                setter.addValue(Pair.of(hostPort[0], port));
+                counter++;
+            }
+            return counter;
+        }
+
+        @Override
+        public String getDefaultMetaVariable() {
+            return "addresses";
+        }
+
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SocketTweetGeneratorDriver.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SocketTweetGeneratorDriver.java
new file mode 100644
index 0000000..d64809f
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SocketTweetGeneratorDriver.java
@@ -0,0 +1,47 @@
+/*
+ * 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.asterix.experiment.client;
+
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+
+public class SocketTweetGeneratorDriver {
+    public static void main(String[] args) throws Exception {
+        SocketTweetGeneratorConfig clientConfig = new SocketTweetGeneratorConfig();
+        CmdLineParser clp = new CmdLineParser(clientConfig);
+        try {
+            clp.parseArgument(args);
+        } catch (CmdLineException e) {
+            System.err.println(e.getMessage());
+            clp.printUsage(System.err);
+            System.exit(1);
+        }
+
+        if ((clientConfig.getDataInterval() == -1 && clientConfig.getDataGenDuration() == -1)
+                || (clientConfig.getDataInterval() > 0 && clientConfig.getDataGenDuration() > 0)) {
+            System.err.println("Must use exactly one of -d or -di");
+            clp.printUsage(System.err);
+            System.exit(1);
+        }
+
+        SocketTweetGenerator client = new SocketTweetGenerator(clientConfig);
+        client.start();
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SpatialIndexExperiment2OrchestratorServer.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SpatialIndexExperiment2OrchestratorServer.java
new file mode 100644
index 0000000..4e360dd
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SpatialIndexExperiment2OrchestratorServer.java
@@ -0,0 +1,179 @@
+/*
+ * 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.asterix.experiment.client;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class SpatialIndexExperiment2OrchestratorServer {
+
+    private static final Logger LOGGER = Logger.getLogger(SpatialIndexExperiment2OrchestratorServer.class.getName());
+
+    private final int dataGenPort;
+
+    private final int queryGenPort;
+
+    private final int nDataGens;
+
+    private final int nQueryGens;
+
+    private final int nIntervals;
+
+    private final AtomicBoolean running;
+
+    public SpatialIndexExperiment2OrchestratorServer(int dataGenPort, int nDataGens, int nIntervals, int queryGenPort,
+            int nQueryGens) {
+        this.dataGenPort = dataGenPort;
+        this.nDataGens = nDataGens;
+        this.queryGenPort = queryGenPort;
+        this.nQueryGens = nQueryGens;
+        this.nIntervals = nIntervals;
+        running = new AtomicBoolean();
+    }
+
+    public synchronized void start() throws IOException, InterruptedException {
+        final AtomicBoolean dataGenBound = new AtomicBoolean();
+        final AtomicBoolean queryGenBound = new AtomicBoolean();
+        running.set(true);
+        Thread t = new Thread(new Runnable() {
+
+            @Override
+            public void run() {
+                try {
+                    ServerSocket dataGenSS = new ServerSocket(dataGenPort);
+                    synchronized (dataGenBound) {
+                        dataGenBound.set(true);
+                        dataGenBound.notifyAll();
+                    }
+                    ServerSocket queryGenSS = new ServerSocket(queryGenPort);
+                    synchronized (queryGenBound) {
+                        queryGenBound.set(true);
+                        queryGenBound.notifyAll();
+                    }
+
+                    Socket[] dataConn = new Socket[nDataGens];
+                    Socket[] queryConn = new Socket[nQueryGens];
+                    try {
+                        //#.wait until all dataGens and queryGens have connected to the orchestrator
+                        for (int i = 0; i < nDataGens; i++) {
+                            dataConn[i] = dataGenSS.accept();
+                        }
+                        for (int i = 0; i < nQueryGens; i++) {
+                            queryConn[i] = queryGenSS.accept();
+                        }
+
+                        //#.wait until queryGens are ready for generating query
+                        for (int i = 0; i < nQueryGens; i++) {
+                            receiveReached(queryConn[i]);
+                        }
+
+                        //#.wait until dataGens are ready for generating data after nIntervals of data were generated 
+                        for (int i = 0; i < nIntervals; i++) {
+                            for (int j = 0; j < nDataGens; j++) {
+                                receiveReached(dataConn[j]);
+                            }
+                        }
+
+                        //#.send signal to queryGens to start sending queries
+                        for (int i = 0; i < nQueryGens; i++) {
+                            sendResume(queryConn[i]);
+                        }
+                        //#.send signal to dataGens to start sending records
+                        for (int i = 0; i < nDataGens; i++) {
+                            sendResume(dataConn[i]);
+                        }
+
+                        //#.wait until both dataGen and queryGen's are done
+                        for (int i = 0; i < nQueryGens; i++) {
+                            receiveReached(queryConn[i]);
+                        }
+                        for (int i = 0; i < nDataGens; i++) {
+                            receiveReached(dataConn[i]);
+                        }
+
+                    } finally {
+                        for (int i = 0; i < nDataGens; ++i) {
+                            if (dataConn[i] != null) {
+                                dataConn[i].close();
+                            }
+                        }
+                        dataGenSS.close();
+                        for (int i = 0; i < nQueryGens; ++i) {
+                            if (queryConn[i] != null) {
+                                queryConn[i].close();
+                            }
+                        }
+                        queryGenSS.close();
+                    }
+                    running.set(false);
+                    synchronized (SpatialIndexExperiment2OrchestratorServer.this) {
+                        SpatialIndexExperiment2OrchestratorServer.this.notifyAll();
+                    }
+                } catch (Throwable t) {
+                    t.printStackTrace();
+                }
+            }
+
+        });
+        t.start();
+        synchronized (dataGenBound) {
+            while (!dataGenBound.get()) {
+                dataGenBound.wait();
+            }
+        }
+        synchronized (queryGenBound) {
+            while (!queryGenBound.get()) {
+                queryGenBound.wait();
+            }    
+        }
+    }
+
+    private static void receiveReached(Socket conn) throws IOException {
+        int msg = new DataInputStream(conn.getInputStream()).readInt();
+        OrchestratorDGProtocol msgType = OrchestratorDGProtocol.values()[msg];
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info("Received " + msgType + " from " + conn.getRemoteSocketAddress());
+        }
+        if (msgType != OrchestratorDGProtocol.REACHED) {
+            throw new IllegalStateException("Encounted unknown message type " + msgType);
+        }
+    }
+
+    private void sendResume(Socket s) throws IOException {
+        new DataOutputStream(s.getOutputStream()).writeInt(OrchestratorDGProtocol.RESUME.ordinal());
+        s.getOutputStream().flush();
+        if (LOGGER.isLoggable(Level.INFO)) {
+            LOGGER.info("Sent " + OrchestratorDGProtocol.RESUME + " to " + s.getRemoteSocketAddress());
+        }
+    }
+
+    public synchronized void awaitFinished() throws InterruptedException {
+        while (running.get()) {
+            wait();
+        }
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SpatialQueryGenerator.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SpatialQueryGenerator.java
new file mode 100644
index 0000000..c046f4e
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SpatialQueryGenerator.java
@@ -0,0 +1,315 @@
+/*
+ * 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.asterix.experiment.client;
+
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Socket;
+import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.asterix.experiment.action.base.IAction;
+import org.apache.asterix.experiment.action.base.SequentialActionList;
+import org.apache.asterix.experiment.action.derived.RunAQLStringAction;
+import org.apache.asterix.experiment.action.derived.TimedAction;
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.hyracks.api.util.ExperimentProfilerUtils;
+
+public class SpatialQueryGenerator {
+
+    private static final int SKIP_LINE_COUNT = 199;
+
+    private final ExecutorService threadPool;
+
+    private final int partitionRangeStart;
+
+    private final int duration;
+
+    private final String restHost;
+
+    private final int restPort;
+
+    private final String orchHost;
+
+    private final int orchPort;
+
+    private final String openStreetMapFilePath;
+
+    private final boolean isIndexOnlyPlan;
+
+    public SpatialQueryGenerator(SpatialQueryGeneratorConfig config) {
+        threadPool = Executors.newCachedThreadPool(new ThreadFactory() {
+
+            private final AtomicInteger count = new AtomicInteger();
+
+            @Override
+            public Thread newThread(Runnable r) {
+                int tid = count.getAndIncrement();
+                Thread t = new Thread(r, "DataGeneratorThread: " + tid);
+                t.setDaemon(true);
+                return t;
+            }
+        });
+
+        partitionRangeStart = config.getPartitionRangeStart();
+        duration = config.getDuration();
+        restHost = config.getRESTHost();
+        restPort = config.getRESTPort();
+        orchHost = config.getQueryOrchestratorHost();
+        orchPort = config.getQueryOrchestratorPort();
+        openStreetMapFilePath = config.getOpenStreetMapFilePath();
+        isIndexOnlyPlan = config.getIsIndexOnlyPlan();
+    }
+
+    public void start() throws Exception {
+        final Semaphore sem = new Semaphore(0);
+        threadPool.submit(new QueryGenerator(sem, restHost, restPort, orchHost, orchPort, partitionRangeStart,
+                duration, openStreetMapFilePath, isIndexOnlyPlan));
+        sem.acquire();
+    }
+
+    public static class QueryGenerator implements Runnable {
+
+        private static final Logger LOGGER = Logger.getLogger(QueryGenerator.class.getName());
+
+        private final HttpClient httpClient;
+        private final Semaphore sem;
+        private final String restHost;
+        private final int restPort;
+        private final String orchHost;
+        private final int orchPort;
+        private final int partition;
+        private final int queryDuration;
+        private final String openStreetMapFilePath;
+        private final float[] radiusType = new float[] { 0.00001f, 0.0001f, 0.001f, 0.01f, 0.1f };
+        private int radiusIter = 0;
+        private final Random randGen;
+        private BufferedReader br;
+        private long queryCount;
+        private Random random = new Random(211);
+        private final boolean isIndexOnlyPlan;
+        private String outputFilePath;
+        private FileOutputStream outputFos;
+
+        public QueryGenerator(Semaphore sem, String restHost, int restPort, String orchHost, int orchPort,
+                int partitionRangeStart, int queryDuration, String openStreetMapFilePath, boolean isIndexOnlyPlan) {
+            httpClient = new DefaultHttpClient();
+            this.sem = sem;
+            this.restHost = restHost;
+            this.restPort = restPort;
+            this.orchHost = orchHost;
+            this.orchPort = orchPort;
+            this.partition = partitionRangeStart;
+            this.queryDuration = queryDuration * 1000;
+            this.openStreetMapFilePath = openStreetMapFilePath;
+            this.queryCount = 0;
+            this.randGen = new Random(partitionRangeStart);
+            this.isIndexOnlyPlan = isIndexOnlyPlan;
+        }
+
+        @Override
+        public void run() {
+            LOGGER.info("\nQueryGen[" + partition + "] running with the following parameters: \n"
+                    + "queryGenDuration : " + queryDuration + "\n" + "isIndexOnlyPlan : " + isIndexOnlyPlan);
+
+            try {
+                outputFilePath = openStreetMapFilePath.substring(0, openStreetMapFilePath.lastIndexOf(File.separator))
+                        + File.separator + "QueryGenResult-" + Inet4Address.getLocalHost().getHostAddress() + ".txt";
+                outputFos = ExperimentProfilerUtils.openOutputFile(outputFilePath);
+            } catch (Exception e) {
+                e.printStackTrace();
+                return;
+            }
+
+            try {
+                if (openStreetMapFilePath != null) {
+                    this.br = new BufferedReader(new FileReader(openStreetMapFilePath));
+                }
+                try {
+                    //connect to orchestrator socket
+                    Socket orchSocket = null;
+                    orchSocket = new Socket(orchHost, orchPort);
+                    try {
+                        //send reached message to orchestrator
+                        sendReached(orchSocket);
+
+                        //wait until receiving resume message from the orchestrator server
+                        receiveResume(orchSocket);
+
+                        if (LOGGER.isLoggable(Level.INFO)) {
+                            LOGGER.info("QueryGen[" + partition + "] starts sending queries...");
+                        }
+                        //send queries during query duration
+                        long startTS = System.currentTimeMillis();
+                        long prevTS = startTS;
+                        long curTS = startTS;
+                        while (curTS - startTS < queryDuration) {
+                            sendQuery();
+                            queryCount++;
+                            curTS = System.currentTimeMillis();
+                            if (LOGGER.isLoggable(Level.INFO) && queryCount % 100 == 0) {
+                                LOGGER.info("QueryGen[" + partition + "][TimeToQuery100] " + (curTS - prevTS)
+                                        + " in milliseconds");
+                                prevTS = curTS;
+                            }
+                        }
+                        if (LOGGER.isLoggable(Level.INFO)) {
+                            LOGGER.info("QueryGen[" + partition + "][QueryCount] " + queryCount + " in "
+                                    + (queryDuration / 1000) + " seconds");
+                        }
+
+                        if (outputFos != null) {
+                            ExperimentProfilerUtils.closeOutputFile(outputFos);
+                        }
+
+                        //send reqched message to orchestrator
+                        sendReached(orchSocket);
+                    } finally {
+                        if (orchSocket != null) {
+                            orchSocket.close();
+                        }
+                    }
+                } catch (Throwable t) {
+                    t.printStackTrace();
+                    outputFos.write("Error during sending query\n".getBytes());
+                    throw t;
+                } finally {
+                    if (openStreetMapFilePath != null) {
+                        br.close();
+                    }
+                    if (outputFos != null) {
+                        ExperimentProfilerUtils.closeOutputFile(outputFos);
+                    }
+                }
+            } catch (Throwable t) {
+                System.err.println("Error connecting to rest API server " + restHost + ":" + restPort);
+                t.printStackTrace();
+            } finally {
+                sem.release();
+            }
+        }
+
+        private void sendQuery() throws IOException {
+            //prepare radius and center point
+            int skipLineCount = SKIP_LINE_COUNT;
+            int lineCount = 0;
+            String line = null;;
+            String strPoints[] = null;
+            float x = 0, y = 0;
+            int beginX = -180, endX = 180, beginY = -90, endY = 90;
+            if (openStreetMapFilePath != null) {
+                while (lineCount < skipLineCount) {
+                    if ((line = br.readLine()) == null) {
+                        //reopen file
+                        br.close();
+                        br = new BufferedReader(new FileReader(openStreetMapFilePath));
+                        line = br.readLine();
+                    }
+                    strPoints = line.split(",");
+                    if (strPoints.length != 2) {
+                        continue;
+                    }
+                    lineCount++;
+                }
+                y = Float.parseFloat(strPoints[0]) / 10000000; //latitude (y value)
+                x = Float.parseFloat(strPoints[1]) / 10000000; //longitude (x value)
+            } else {
+                int xMajor = beginX + random.nextInt(endX - beginX);
+                int xMinor = random.nextInt(100);
+                x = xMajor + ((float) xMinor) / 100;
+
+                int yMajor = beginY + random.nextInt(endY - beginY);
+                int yMinor = random.nextInt(100);
+                y = yMajor + ((float) yMinor) / 100;
+            }
+
+            //create action
+            SequentialActionList sAction = new SequentialActionList();
+            IAction rangeQueryAction = new TimedAction(new RunAQLStringAction(httpClient, restHost, restPort,
+                    getRangeQueryAQL(radiusType[radiusIter++ % radiusType.length], x, y, isIndexOnlyPlan), outputFos),
+                    outputFos);
+            sAction.add(rangeQueryAction);
+
+            //perform
+            sAction.perform();
+        }
+
+        private String getRangeQueryAQL(float radius, float x, float y, boolean isIndexOnlyPlan) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("use dataverse experiments; ");
+            sb.append("count( ");
+            sb.append("for $x in dataset Tweets").append(" ");
+            sb.append("let $n :=  create-circle( ");
+            sb.append("point(\"").append(x).append(", ").append(y).append("\") ");
+            sb.append(", ");
+            sb.append(String.format("%f", radius));
+            sb.append(" )");
+            if (isIndexOnlyPlan) {
+                sb.append("where spatial-intersect($x.sender-location, $n) ");
+            } else {
+                sb.append("where spatial-intersect($x.sender-location, $n) and $x.btree-extra-field1 <= int32(\"2147483647\") ");
+            }
+            sb.append("return $x ");
+            sb.append(");");
+            return sb.toString();
+        }
+
+        private void sendReached(Socket s) throws IOException {
+            new DataOutputStream(s.getOutputStream()).writeInt(OrchestratorDGProtocol.REACHED.ordinal());
+            s.getOutputStream().flush();
+            if (LOGGER.isLoggable(Level.INFO)) {
+                LOGGER.info("Sent " + OrchestratorDGProtocol.REACHED + " to " + s.getRemoteSocketAddress());
+            }
+        }
+
+        private void receiveResume(Socket s) throws IOException {
+            int msg = new DataInputStream(s.getInputStream()).readInt();
+            OrchestratorDGProtocol msgType = OrchestratorDGProtocol.values()[msg];
+            if (LOGGER.isLoggable(Level.INFO)) {
+                LOGGER.info("Received " + msgType + " from " + s.getRemoteSocketAddress());
+            }
+            if (msgType != OrchestratorDGProtocol.RESUME) {
+                throw new IllegalStateException("Unknown protocol message received: " + msgType);
+            }
+        }
+
+        private void sendStopped(Socket s) throws IOException {
+            new DataOutputStream(s.getOutputStream()).writeInt(OrchestratorDGProtocol.STOPPED.ordinal());
+            s.getOutputStream().flush();
+            if (LOGGER.isLoggable(Level.INFO)) {
+                LOGGER.info("Sent " + OrchestratorDGProtocol.STOPPED + " to " + s.getRemoteSocketAddress());
+            }
+        }
+
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SpatialQueryGeneratorConfig.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SpatialQueryGeneratorConfig.java
new file mode 100644
index 0000000..79055aa
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SpatialQueryGeneratorConfig.java
@@ -0,0 +1,135 @@
+/*
+ * 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.asterix.experiment.client;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.Option;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.OptionHandler;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
+
+public class SpatialQueryGeneratorConfig {
+
+    @Option(name = "-p", aliases = "--partition-range-start", usage = "Starting partition number for the set of data generators (default = 0)")
+    private int partitionRangeStart = 0;
+
+    public int getPartitionRangeStart() {
+        return partitionRangeStart;
+    }
+
+    @Option(name = "-qd", aliases = { "--duration" }, usage = "Duration in seconds to run guery generation")
+    private int queryGenDuration = -1;
+
+    public int getDuration() {
+        return queryGenDuration;
+    }
+
+    @Option(name = "-qc", aliases = { "--query-count" }, usage = "The number of queries to generate")
+    private int queryCount = -1;
+
+    public int getQueryCount() {
+        return queryCount;
+    }
+
+    @Option(name = "-rh", aliases = "--rest-host", usage = "Asterix REST API host address", required = true, metaVar = "HOST")
+    private String restHost;
+
+    public String getRESTHost() {
+        return restHost;
+    }
+
+    @Option(name = "-rp", aliases = "--rest-port", usage = "Asterix REST API port", required = true, metaVar = "PORT")
+    private int restPort;
+
+    public int getRESTPort() {
+        return restPort;
+    }
+
+    @Option(name = "-qoh", aliases = "--query-orchestrator-host", usage = "The host address of query orchestrator")
+    private String queryOrchHost;
+
+    public String getQueryOrchestratorHost() {
+        return queryOrchHost;
+    }
+
+    @Option(name = "-qop", aliases = "--query-orchestrator-port", usage = "The port to be used for the orchestrator server of query orchestrator")
+    private int queryOrchPort;
+
+    public int getQueryOrchestratorPort() {
+        return queryOrchPort;
+    }
+
+    @Option(name = "-of", aliases = "--openstreetmap-filepath", usage = "The open street map gps point data file path")
+    private String openStreetMapFilePath;
+
+    public String getOpenStreetMapFilePath() {
+        return openStreetMapFilePath;
+    }
+
+    @Option(name = "-iop", aliases = "--index-only-plan", usage = "Indicator of whether index only plan or not")
+    private boolean isIndexOnlyPlan;
+
+    public boolean getIsIndexOnlyPlan() {
+        return isIndexOnlyPlan;
+    }
+
+    public static class AddressOptionHandler extends OptionHandler<Pair<String, Integer>> {
+
+        public AddressOptionHandler(CmdLineParser parser, OptionDef option, Setter<? super Pair<String, Integer>> setter) {
+            super(parser, option, setter);
+        }
+
+        @Override
+        public int parseArguments(Parameters params) throws CmdLineException {
+            int counter = 0;
+            while (true) {
+                String param;
+                try {
+                    param = params.getParameter(counter);
+                } catch (CmdLineException ex) {
+                    break;
+                }
+
+                String[] hostPort = param.split(":");
+                if (hostPort.length != 2) {
+                    throw new CmdLineException("Invalid address: " + param + ". Expected <host>:<port>");
+                }
+                Integer port = null;
+                try {
+                    port = Integer.parseInt(hostPort[1]);
+                } catch (NumberFormatException e) {
+                    throw new CmdLineException("Invalid port " + hostPort[1] + " for address " + param + ".");
+                }
+                setter.addValue(Pair.of(hostPort[0], port));
+                counter++;
+            }
+            return counter;
+        }
+
+        @Override
+        public String getDefaultMetaVariable() {
+            return "addresses";
+        }
+
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SpatialQueryGeneratorDriver.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SpatialQueryGeneratorDriver.java
new file mode 100644
index 0000000..ee16340
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SpatialQueryGeneratorDriver.java
@@ -0,0 +1,40 @@
+/*
+ * 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.asterix.experiment.client;
+
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+
+public class SpatialQueryGeneratorDriver {
+    public static void main(String[] args) throws Exception {
+        SpatialQueryGeneratorConfig clientConfig = new SpatialQueryGeneratorConfig();
+        CmdLineParser clp = new CmdLineParser(clientConfig);
+        try {
+            clp.parseArgument(args);
+        } catch (CmdLineException e) {
+            System.err.println(e.getMessage());
+            clp.printUsage(System.err);
+            System.exit(1);
+        }
+
+        SpatialQueryGenerator client = new SpatialQueryGenerator(clientConfig);
+        client.start();
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SyntheticDataGeneratorConfig.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SyntheticDataGeneratorConfig.java
new file mode 100644
index 0000000..8621681
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SyntheticDataGeneratorConfig.java
@@ -0,0 +1,60 @@
+/*
+ * 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.asterix.experiment.client;
+
+import org.kohsuke.args4j.Option;
+
+public class SyntheticDataGeneratorConfig {
+
+    @Option(name = "-psf", aliases = "--point-source-file", usage = "The point source file")
+    private String pointSourceFile;
+
+    public String getPointSourceFile() {
+        return pointSourceFile;
+    }
+    
+    @Option(name = "-psi", aliases = "--point-sampling-interval", usage = "The point sampling interval from the point source file", required = true)
+    private int pointSamplingInterval;
+
+    public int getpointSamplingInterval() {
+        return pointSamplingInterval;
+    }
+    
+    @Option(name = "-pid", aliases = "--parition-id", usage = "The partition id in order to avoid key duplication", required = true)
+    private int partitionId;
+
+    public int getPartitionId() {
+        return partitionId;
+    }
+    
+    @Option(name = "-of", aliases = "--output-filepath", usage = "The output file path", required = true)
+    private String outputFilePath;
+
+    public String getOutputFilePath() {
+        return outputFilePath;
+    }
+    
+    @Option(name = "-rc", aliases = "--record-count", usage = "The record count to generate", required = true)
+    private long recordCount;
+
+    public long getRecordCount() {
+        return recordCount;
+    }        
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SyntheticDataGeneratorForSpatialIndexEvaluation.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SyntheticDataGeneratorForSpatialIndexEvaluation.java
new file mode 100644
index 0000000..10bae07
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/client/SyntheticDataGeneratorForSpatialIndexEvaluation.java
@@ -0,0 +1,106 @@
+/*
+ * 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.asterix.experiment.client;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+
+import org.apache.asterix.tools.external.data.DataGeneratorForSpatialIndexEvaluation;
+import org.apache.asterix.tools.external.data.DataGeneratorForSpatialIndexEvaluation.InitializationInfo;
+import org.apache.asterix.tools.external.data.DataGeneratorForSpatialIndexEvaluation.TweetMessageIterator;
+import org.apache.asterix.tools.external.data.GULongIDGenerator;
+
+public class SyntheticDataGeneratorForSpatialIndexEvaluation {
+    public static void main(String[] args) throws Exception {
+        SyntheticDataGeneratorConfig config = new SyntheticDataGeneratorConfig();
+        CmdLineParser clp = new CmdLineParser(config);
+        try {
+            clp.parseArgument(args);
+        } catch (CmdLineException e) {
+            System.err.println(e.getMessage());
+            clp.printUsage(System.err);
+            System.exit(1);
+        }
+
+        //prepare data generator
+        GULongIDGenerator uidGenerator = new GULongIDGenerator(config.getPartitionId(), (byte) (0));
+        String pointSourceFilePath = config.getPointSourceFile();
+        int pointSampleInterval = config.getpointSamplingInterval();
+        DataGeneratorForSpatialIndexEvaluation dataGenerator = new DataGeneratorForSpatialIndexEvaluation(new InitializationInfo(), pointSourceFilePath,
+                pointSampleInterval);
+
+        //get record count to be generated
+        long maxRecordCount = config.getRecordCount();
+        long recordCount = 0;
+
+        //prepare timer
+        long startTS = System.currentTimeMillis();
+
+        //prepare tweetIterator which acutally generates tweet 
+        TweetMessageIterator tweetIterator = dataGenerator.new TweetMessageIterator(0, uidGenerator);
+
+        FileOutputStream fos = null;
+        try {
+            //prepare output file
+            fos = openOutputFile(config.getOutputFilePath());
+
+            while (recordCount < maxRecordCount) {
+                //get a tweet and append newline at the end
+                String tweet = tweetIterator.next().toString() + "\n";
+                //write to file
+                fos.write(tweet.getBytes());
+                
+                recordCount++;
+                if (recordCount % 1000000 == 0) {
+                    System.out.println("... generated " + recordCount + " records");
+                }
+            }
+            System.out.println("Done: generated " + recordCount + " records in "
+                    + ((System.currentTimeMillis() - startTS) / 1000) + " in seconds!");
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                closeOutputFile(fos);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public static FileOutputStream openOutputFile(String filepath) throws IOException {
+        File file = new File(filepath);
+        if (file.exists()) {
+            throw new IOException(filepath + "already exists");
+        }
+        file.createNewFile();
+        return new FileOutputStream(file);
+    }
+
+    public static void closeOutputFile(FileOutputStream fos) throws IOException {
+        fos.flush();
+        fos.close();
+        fos = null;
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/logging/ExperimentLogFormatter.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/logging/ExperimentLogFormatter.java
new file mode 100644
index 0000000..544fbf8
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/logging/ExperimentLogFormatter.java
@@ -0,0 +1,128 @@
+/*
+ * 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.asterix.experiment.logging;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.logging.Formatter;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+public class ExperimentLogFormatter extends Formatter {
+
+    // format string for printing the log record
+    private static final String format = "{0} {1}\n{2}: {3}\n";
+    private final Date dat = new Date();
+    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+    /**
+     * Format the given LogRecord.
+     * <p>
+     * The formatting can be customized by specifying the <a href="../Formatter.html#syntax">format string</a> in the <a href="#formatting"> {@code java.util.logging.SimpleFormatter.format}</a> property. The given {@code LogRecord} will be formatted as if by calling:
+     * 
+     * <pre>
+     *    {@link String#format String.format}(format, date, source, logger, level, message, thrown);
+     * </pre>
+     * 
+     * where the arguments are:<br>
+     * <ol>
+     * <li>{@code format} - the {@link java.util.Formatter
+     * java.util.Formatter} format string specified in the {@code java.util.logging.SimpleFormatter.format} property or the default format.</li>
+     * <li>{@code date} - a {@link Date} object representing {@linkplain LogRecord#getMillis event time} of the log record.</li>
+     * <li>{@code source} - a string representing the caller, if available; otherwise, the logger's name.</li>
+     * <li>{@code logger} - the logger's name.</li>
+     * <li>{@code level} - the {@linkplain Level#getLocalizedName
+     * log level}.</li>
+     * <li>{@code message} - the formatted log message returned from the {@link Formatter#formatMessage(LogRecord)} method. It uses {@link java.text.MessageFormat java.text} formatting and does not use the {@code java.util.Formatter format} argument.</li>
+     * <li>{@code thrown} - a string representing the {@linkplain LogRecord#getThrown throwable} associated with the log record and its backtrace beginning with a newline character, if any; otherwise, an empty string.</li>
+     * </ol>
+     * <p>
+     * Some example formats:<br>
+     * <ul>
+     * <li> {@code java.util.logging.SimpleFormatter.format="%4$s: %5$s [%1$tc]%n"}
+     * <p>
+     * This prints 1 line with the log level ({@code 4$}), the log message ({@code 5$}) and the timestamp ({@code 1$}) in a square bracket.
+     * 
+     * <pre>
+     *     WARNING: warning message [Tue Mar 22 13:11:31 PDT 2011]
+     * </pre>
+     * 
+     * </li>
+     * <li> {@code java.util.logging.SimpleFormatter.format="%1$tc %2$s%n%4$s: %5$s%6$s%n"}
+     * <p>
+     * This prints 2 lines where the first line includes the timestamp ({@code 1$}) and the source ({@code 2$}); the second line includes the log level ({@code 4$}) and the log message ({@code 5$}) followed with the throwable and its backtrace ({@code 6$}), if any:
+     * 
+     * <pre>
+     *     Tue Mar 22 13:11:31 PDT 2011 MyClass fatal
+     *     SEVERE: several message with an exception
+     *     java.lang.IllegalArgumentException: invalid argument
+     *             at MyClass.mash(MyClass.java:9)
+     *             at MyClass.crunch(MyClass.java:6)
+     *             at MyClass.main(MyClass.java:3)
+     * </pre>
+     * 
+     * </li>
+     * <li> {@code java.util.logging.SimpleFormatter.format="%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s%n%4$s: %5$s%n"}
+     * <p>
+     * This prints 2 lines similar to the example above with a different date/time formatting and does not print the throwable and its backtrace:
+     * 
+     * <pre>
+     *     Mar 22, 2011 1:11:31 PM MyClass fatal
+     *     SEVERE: several message with an exception
+     * </pre>
+     * 
+     * </li>
+     * </ul>
+     * <p>
+     * This method can also be overridden in a subclass. It is recommended to use the {@link Formatter#formatMessage} convenience method to localize and format the message field.
+     * 
+     * @param record
+     *            the log record to be formatted.
+     * @return a formatted log record
+     */
+    public synchronized String format(LogRecord record) {
+        dat.setTime(record.getMillis());
+        String source;
+        if (record.getSourceClassName() != null) {
+            source = record.getSourceClassName();
+            if (record.getSourceMethodName() != null) {
+                source += " " + record.getSourceMethodName();
+            }
+        } else {
+            source = record.getLoggerName();
+        }
+        String message = formatMessage(record);
+        String throwable = "";
+        if (record.getThrown() != null) {
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            pw.println();
+            record.getThrown().printStackTrace(pw);
+            pw.close();
+            throwable = sw.toString();
+        }
+        return MessageFormat.format(format, sdf.format(dat), source, record.getLevel(),
+                message, throwable);
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/AbstractDynamicDataEvalReportBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/AbstractDynamicDataEvalReportBuilder.java
new file mode 100644
index 0000000..13d2694
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/AbstractDynamicDataEvalReportBuilder.java
@@ -0,0 +1,286 @@
+/*
+ * 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.asterix.experiment.report;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.List;
+
+public abstract class AbstractDynamicDataEvalReportBuilder implements IDynamicDataEvalReportBuilder {
+
+    protected final static String INSTANTANEOUS_INSERT_STRING = "[TimeToInsert100000]";
+    protected final static int INSTANTAEOUS_INSERT_COUNT = 100000;
+    protected final static int ROUND_COUNT = 721;
+    protected final static int ROUND_INTERVAL = 5;
+    protected final String expHomePath;
+    protected final String expName;
+    protected final String runLogFilePath;
+    protected final String[] ncLogFilePaths;
+    protected BufferedReader br = null;
+    protected BufferedReader[] ncLogBrs = null;
+    protected final int ncLogFileCount;
+
+    protected final StringBuilder dataGenSb;
+    protected final StringBuilder queryGenSb;
+    protected final StringBuilder rsb;
+
+    protected AbstractDynamicDataEvalReportBuilder(String expHomePath, String expName, String runLogFileName,
+            boolean hasStatFile) {
+        this.expHomePath = expHomePath;
+        this.expName = expName;
+        this.runLogFilePath = new String(expHomePath + runLogFileName);
+        if (expName.contains("1A")) {
+            ncLogFileCount = 1;
+        } else if (expName.contains("1B")) {
+            ncLogFileCount = 2;
+        } else if (expName.contains("1C")) {
+            ncLogFileCount = 4;
+        } else /* if (expName.contains("1D") || other exps) */{
+            ncLogFileCount = 8;
+        }
+        ncLogFilePaths = new String[ncLogFileCount];
+        ncLogBrs = new BufferedReader[ncLogFileCount];
+        for (int i = 0; i < ncLogFileCount; i++) {
+            if (hasStatFile) {
+                ncLogFilePaths[i] = new String(expHomePath + expName + File.separator + "node" + (i + 1)
+                        + File.separator + "logs" + File.separator + "a1_node" + (i + 1) + ".log");
+            } else {
+                ncLogFilePaths[i] = new String(expHomePath + expName + File.separator + "logs" + File.separator
+                        + "a1_node" + (i + 1) + ".log");
+            }
+        }
+        dataGenSb = new StringBuilder();
+        queryGenSb = new StringBuilder();
+        rsb = new StringBuilder();
+    }
+
+    protected void openRunLog() throws IOException {
+        br = new BufferedReader(new FileReader(runLogFilePath));
+        for (int i = 0; i < ncLogFileCount; i++) {
+            ncLogBrs[i] = new BufferedReader(new FileReader(ncLogFilePaths[i]));
+        }
+    }
+
+    protected void closeRunLog() throws IOException {
+        if (br != null) {
+            br.close();
+        }
+        if (ncLogBrs != null) {
+            for (int i = 0; i < ncLogFileCount; i++) {
+                if (ncLogBrs[i] != null) {
+                    ncLogBrs[i].close();
+                }
+            }
+        }
+    }
+
+    protected boolean moveToExperimentBegin() throws IOException {
+        String line;
+        while ((line = br.readLine()) != null) {
+            if (line.contains("Running experiment: " + expName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    protected void renewStringBuilder() {
+        dataGenSb.setLength(0);
+        queryGenSb.setLength(0);
+        rsb.setLength(0);
+    }
+
+    @Override
+    public String getInstantaneousInsertPS(int nodeId, boolean useTimeForX) throws Exception {
+        renewStringBuilder();
+        openRunLog();
+        try {
+
+            if (!moveToExperimentBegin()) {
+                //The experiment run log doesn't exist in this run log file
+                return null;
+            }
+
+            int round = 0;
+            while (round < ROUND_COUNT) {
+                long IIPS = 0;
+                String line;
+                while ((line = ncLogBrs[nodeId].readLine()) != null) {
+                    if (line.contains("IPS")) {
+                        IIPS = ReportBuilderHelper.getLong(line, ", IIPS[", "]");
+                        break;
+                    }
+                }
+                round++;
+                dataGenSb.append(round * ROUND_INTERVAL).append(",").append(IIPS).append("\n");
+            }
+
+            return dataGenSb.toString();
+        } finally {
+            closeRunLog();
+        }
+    }
+
+    @Override
+    public void getAllNodesAccumulatedInsertPS(int targetRound, List<Long> ipsList) throws Exception {
+        renewStringBuilder();
+        openRunLog();
+        ipsList.clear();
+        try {
+
+            if (!moveToExperimentBegin()) {
+                //The experiment run log doesn't exist in this run log file
+                return;
+            }
+
+            int round = 0;
+            while (round < targetRound) {
+                long IPSPerRound = 0;
+                for (int i = 0; i < ncLogFileCount; i++) {
+                    String line;
+                    while ((line = ncLogBrs[i].readLine()) != null) {
+                        if (line.contains("IPS")) {
+                            IPSPerRound += ReportBuilderHelper.getLong(line, ", IPS[", "]");
+                            break;
+                        }
+                    }
+                }
+                ipsList.add(IPSPerRound);
+                round++;
+            }
+            return;
+        } finally {
+            closeRunLog();
+        }
+    }
+
+    public String getInstantaneousDataGenPS(int genId, boolean useTimeForX) throws Exception {
+        renewStringBuilder();
+        openRunLog();
+        try {
+            if (!moveToExperimentBegin()) {
+                //The experiment run log doesn't exist in this run log file
+                return null;
+            }
+
+            String line;
+            int dGenId;
+            int count = 0;
+            long timeToInsert = 0;
+            long totalTimeToInsert = 0;
+            while ((line = br.readLine()) != null) {
+                if (line.contains(INSTANTANEOUS_INSERT_STRING)) {
+                    dGenId = ReportBuilderHelper.getInt(line, "DataGen[", "]");
+                    if (dGenId == genId) {
+                        count++;
+                        timeToInsert = ReportBuilderHelper.getLong(line, INSTANTANEOUS_INSERT_STRING, "in");
+                        totalTimeToInsert += timeToInsert;
+                        if (useTimeForX) {
+                            dataGenSb.append(totalTimeToInsert / 1000).append(",")
+                                    .append(INSTANTAEOUS_INSERT_COUNT / ((double) (timeToInsert) / 1000)).append("\n");
+                        } else {
+                            dataGenSb.append(count).append(",")
+                                    .append(INSTANTAEOUS_INSERT_COUNT / ((double) (timeToInsert) / 1000)).append("\n");
+                        }
+                    }
+                }
+                if (line.contains("Running")) {
+                    break;
+                }
+            }
+            System.out.println("GenId[" + genId + "] " + totalTimeToInsert + ", " + (totalTimeToInsert / (1000 * 60)));
+            return dataGenSb.toString();
+        } finally {
+            closeRunLog();
+        }
+    }
+
+    public long getDataGenStartTimeStamp() throws Exception {
+        openRunLog();
+        try {
+            String line;
+            while ((line = br.readLine()) != null) {
+                if (line.contains("Running experiment: " + expName)) {
+                    while ((line = br.readLine()) != null) {
+                        //2015-10-27 17:18:28,242 INFO  [ParallelActionThread 6] transport.TransportImpl (TransportImpl.java:init(155)) - Client identity string: SSH-2.0-SSHJ_0_13_0
+                        if (line.contains("INFO  [ParallelActionThread")) {
+                            //format1 = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss aa");
+                            //format2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+                            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+                            return ReportBuilderHelper.getTimeStampAsLong(line, format);
+                        }
+                    }
+                }
+            }
+            return -1;
+        } finally {
+            closeRunLog();
+        }
+    }
+
+    public String getIndexSize(String indexDirPath) throws Exception {
+        /*
+         * exmaple
+         * /mnt/data/sdb/youngsk2/asterix/storage/experiments/Tweets_idx_dhbtreeLocation/device_id_0:
+        total 211200
+        -rw-r--r-- 1 youngsk2 grad 191234048 Jun 29 00:11 2015-06-29-00-09-59-023_2015-06-28-23-51-56-984_b
+        -rw-r--r-- 1 youngsk2 grad   7864320 Jun 29 00:11 2015-06-29-00-09-59-023_2015-06-28-23-51-56-984_f
+        -rw-r--r-- 1 youngsk2 grad   4194304 Jun 29 00:10 2015-06-29-00-10-26-997_2015-06-29-00-10-26-997_b
+        -rw-r--r-- 1 youngsk2 grad    393216 Jun 29 00:10 2015-06-29-00-10-26-997_2015-06-29-00-10-26-997_f
+        -rw-r--r-- 1 youngsk2 grad   5898240 Jun 29 00:11 2015-06-29-00-10-59-791_2015-06-29-00-10-59-791_b
+        -rw-r--r-- 1 youngsk2 grad    393216 Jun 29 00:11 2015-06-29-00-10-59-791_2015-06-29-00-10-59-791_f
+        -rw-r--r-- 1 youngsk2 grad   5898240 Jun 29 00:11 2015-06-29-00-11-30-486_2015-06-29-00-11-30-486_b
+        -rw-r--r-- 1 youngsk2 grad    393216 Jun 29 00:11 2015-06-29-00-11-30-486_2015-06-29-00-11-30-486_f
+        
+         */
+        renewStringBuilder();
+        openRunLog();
+        try {
+            if (!moveToExperimentBegin()) {
+                //The experiment run log doesn't exist in this run log file
+                return null;
+            }
+
+            String line;
+            String[] tokens;
+            long diskSize = 0;
+            while ((line = br.readLine()) != null) {
+                if (line.contains(indexDirPath)) {
+                    br.readLine();//discard "total XXXX" line
+                    //read and sum file size
+                    while (!(line = br.readLine()).isEmpty()) {
+                        tokens = line.split("\\s+");;
+                        diskSize += Long.parseLong(tokens[4].trim());
+                    }
+                }
+                if (line.contains("Running")) {
+                    break;
+                }
+            }
+            rsb.append((double) diskSize / (1024 * 1024 * 1024));
+            return rsb.toString();
+        } finally {
+            closeRunLog();
+        }
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/AbstractStaticDataEvalReportBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/AbstractStaticDataEvalReportBuilder.java
new file mode 100644
index 0000000..fdd1d92
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/AbstractStaticDataEvalReportBuilder.java
@@ -0,0 +1,31 @@
+/*
+ * 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.asterix.experiment.report;
+
+public abstract class AbstractStaticDataEvalReportBuilder implements IStaticDataEvalReportBuilder {
+
+    protected final String expName;
+    protected final String runLogFilePath;
+    
+    protected AbstractStaticDataEvalReportBuilder(String expName, String runLogFilePath) {
+        this.expName = expName;
+        this.runLogFilePath = runLogFilePath;
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/IDynamicDataEvalReportBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/IDynamicDataEvalReportBuilder.java
new file mode 100644
index 0000000..4d5e511
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/IDynamicDataEvalReportBuilder.java
@@ -0,0 +1,34 @@
+/*
+ * 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.asterix.experiment.report;
+
+import java.util.List;
+
+public interface IDynamicDataEvalReportBuilder {
+    public String getInstantaneousInsertPS(int genId, boolean useTimeForX) throws Exception;
+
+    public String getOverallInsertPS(int minutes) throws Exception;
+
+    public String getInstantaneousQueryPS() throws Exception;
+
+    public String getQueryPS(int minutes) throws Exception;
+
+    void getAllNodesAccumulatedInsertPS(int targetRound, List<Long> ipsList) throws Exception;
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/IStaticDataEvalReportBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/IStaticDataEvalReportBuilder.java
new file mode 100644
index 0000000..6c879f4
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/IStaticDataEvalReportBuilder.java
@@ -0,0 +1,25 @@
+/*
+ * 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.asterix.experiment.report;
+
+public interface IStaticDataEvalReportBuilder {
+    public String getSelectQueryTime();
+    public String getJoinQueryTime();
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/NCLogReportBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/NCLogReportBuilder.java
new file mode 100644
index 0000000..5da4463
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/NCLogReportBuilder.java
@@ -0,0 +1,212 @@
+/*
+ * 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.asterix.experiment.report;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+public class NCLogReportBuilder {
+
+    private String ncLogFilePath = "/Users/kisskys/workspace/asterix_experiment/run-log/measure-with-balloon/sie1-8dgen/log-1436511417368/SpatialIndexExperiment1ADhbtree/logs/a1_node1.log";
+    private BufferedReader br;
+    private String timeLine;
+    private String msgLine;
+
+    public NCLogReportBuilder(String filePath) {
+        if (filePath != null) {
+            this.ncLogFilePath = filePath;
+        }
+    }
+
+    public String getFlushMergeEventAsGanttChartFormat(long testBeginTimeStamp) throws Exception {
+        openNCLog();
+        StringBuilder sb = new StringBuilder();
+        long flushStartTimeStamp, flushFinishTimeStamp, mergeStartTimeStamp, mergeFinishTimeStamp;
+        String indexName;
+        SimpleDateFormat format = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss aa");
+        HashMap<String, Long> flushMap = new HashMap<String, Long>();
+        HashMap<String, Long> mergeMap = new HashMap<String, Long>();
+        long sTime, fTime;
+        try {
+            while ((timeLine = br.readLine()) != null) {
+                if ((msgLine = br.readLine()) == null) {
+                    break;
+                }
+                while (!msgLine.contains("INFO:")) {
+                    timeLine = msgLine;
+                    msgLine = br.readLine();
+                    if (msgLine == null) {
+                        break;
+                    }
+                }
+                if (msgLine == null) {
+                    break;
+                }
+
+                //flush start
+                if (msgLine.contains("Started a flush operation for index")) {
+                    flushStartTimeStamp = ReportBuilderHelper.getTimeStampAsLong(timeLine, format);
+
+                    //ignore flush op which happened before the data gen started.
+                    if (flushStartTimeStamp < testBeginTimeStamp) {
+                        continue;
+                    }
+
+                    indexName = ReportBuilderHelper.getString(msgLine, "experiments/Tweets_idx_", "/]");
+                    flushMap.put(indexName, flushStartTimeStamp);
+                }
+
+                //flush finish
+                if (msgLine.contains("Finished the flush operation for index")) {
+                    flushFinishTimeStamp = ReportBuilderHelper.getTimeStampAsLong(timeLine, format);
+
+                    //ignore flush op which happened before the data gen started.
+                    if (flushFinishTimeStamp < testBeginTimeStamp) {
+                        continue;
+                    }
+
+                    indexName = ReportBuilderHelper.getString(msgLine, "experiments/Tweets_idx_", "/]");
+
+                    if (flushMap.containsKey(indexName)) {
+                        flushStartTimeStamp = flushMap.remove(indexName);
+                        sTime = (flushStartTimeStamp - testBeginTimeStamp) / 1000;
+                        fTime = (flushFinishTimeStamp - testBeginTimeStamp) / 1000;
+                        if (fTime == sTime) {
+                            ++fTime;
+                        }
+                        //only for sie1
+                        //                        if (fTime > 1200) {
+                        //                            fTime = 1200;
+                        //                        }
+                        sb.append("f-" + getPrintName(indexName)).append("\t").append(sTime).append("\t").append(fTime)
+                                .append("\t").append(indexName.contains("Tweets") ? "flushPidx" : "flushSidx")
+                                .append("\n");
+                    }
+                }
+
+                //merge start
+                if (msgLine.contains("Started a merge operation for index")) {
+                    mergeStartTimeStamp = ReportBuilderHelper.getTimeStampAsLong(timeLine, format);
+
+                    //ignore flush op which happened before the data gen started.
+                    if (mergeStartTimeStamp < testBeginTimeStamp) {
+                        continue;
+                    }
+
+                    indexName = ReportBuilderHelper.getString(msgLine, "experiments/Tweets_idx_", "/]");
+                    mergeMap.put(indexName, mergeStartTimeStamp);
+                }
+
+                //merge finish
+                if (msgLine.contains("Finished the merge operation for index")) {
+                    mergeFinishTimeStamp = ReportBuilderHelper.getTimeStampAsLong(timeLine, format);
+
+                    //ignore flush op which happened before the data gen started.
+                    if (mergeFinishTimeStamp < testBeginTimeStamp) {
+                        continue;
+                    }
+
+                    indexName = ReportBuilderHelper.getString(msgLine, "experiments/Tweets_idx_", "/]");
+
+                    if (mergeMap.containsKey(indexName)) {
+                        mergeStartTimeStamp = mergeMap.remove(indexName);
+                        sTime = (mergeStartTimeStamp - testBeginTimeStamp) / 1000;
+                        fTime = (mergeFinishTimeStamp - testBeginTimeStamp) / 1000;
+                        if (fTime == sTime) {
+                            ++fTime;
+                        }
+                        //only for sie1
+                        //                        if (fTime > 1200) {
+                        //                            fTime = 1200;
+                        //                        }
+                        sb.append("m-" + getPrintName(indexName)).append("\t").append(sTime).append("\t").append(fTime)
+                                .append("\t").append(indexName.contains("Tweets") ? "mergePidx" : "mergeSidx")
+                                .append("\n");
+                    }
+                }
+            }
+
+            Iterator<Entry<String, Long>> mergeMapIter = mergeMap.entrySet().iterator();
+            Entry<String, Long> entry = null;
+            while (mergeMapIter.hasNext()) {
+                entry = mergeMapIter.next();
+                sb.append("m-" + getPrintName(entry.getKey())).append("\t")
+                        .append((entry.getValue() - testBeginTimeStamp) / 1000).append("\t").append(60 * 20)
+                        .append("\t").append(entry.getKey().contains("Tweets") ? "mergePidx" : "mergeSidx")
+                        .append("\n");
+            }
+
+            Iterator<Entry<String, Long>> flushMapIter = mergeMap.entrySet().iterator();
+            while (mergeMapIter.hasNext()) {
+                entry = flushMapIter.next();
+                sb.append("f-" + getPrintName(entry.getKey())).append("\t")
+                        .append((entry.getValue() - testBeginTimeStamp) / 1000).append("\t").append(60 * 20)
+                        .append("\t").append(entry.getKey().contains("Tweets") ? "flushPidx" : "flushSidx")
+                        .append("\n");
+            }
+
+            return sb.toString();
+        } finally {
+            closeNCLog();
+        }
+    }
+
+    private String getPrintName(String indexName) {
+        String name = null;
+        if (indexName.contains("Tweets")) {
+            if (indexName.contains("0")) {
+                name = "pidx0";
+            } else if (indexName.contains("1")) {
+                name = "pidx1";
+            } else if (indexName.contains("2")) {
+                name = "pidx2";
+            } else if (indexName.contains("3")) {
+                name = "pidx3";
+            }
+        } else if (indexName.contains("Location")) {
+            if (indexName.contains("0")) {
+                name = "sidx0"; //ReportBuilderHelper.getString(indexName, "Location") + "0";
+            } else if (indexName.contains("1")) {
+                name = "sidx1"; //ReportBuilderHelper.getString(indexName, "Location") + "1";
+            } else if (indexName.contains("2")) {
+                name = "sidx2"; //ReportBuilderHelper.getString(indexName, "Location") + "2";
+            } else if (indexName.contains("3")) {
+                name = "sidx3"; //ReportBuilderHelper.getString(indexName, "Location") + "2";
+            }
+        }
+        return name;
+    }
+
+    protected void openNCLog() throws IOException {
+        br = new BufferedReader(new FileReader(ncLogFilePath));
+    }
+
+    protected void closeNCLog() throws IOException {
+        if (br != null) {
+            br.close();
+        }
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/OperatorProfilerReportBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/OperatorProfilerReportBuilder.java
new file mode 100644
index 0000000..24617bb
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/OperatorProfilerReportBuilder.java
@@ -0,0 +1,322 @@
+/*
+ * 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.asterix.experiment.report;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+public class OperatorProfilerReportBuilder {
+
+    private static final int INDEX_BUILD_OP_COUNT = 1;
+    private static final int PIDX_SCAN_OP_COUNT = 1;
+    private static final int WARM_UP_SELECT_QUERY_COUNT = 500;
+    private static final int SELECT_QUERY_COUNT = 5000;
+    private static final int JOIN_QUERY_COUNT = 200;
+    private static final int JOIN_RADIUS_TYPE_COUNT = 4;
+    private static final int SELECT_RADIUS_TYPE_COUNT = 5;
+    private static final int IDX_JOIN_RADIUS_SKIP = JOIN_RADIUS_TYPE_COUNT - 1;
+    private static final int IDX_SELECT_RADIUS_SKIP = SELECT_RADIUS_TYPE_COUNT - 1;
+    private static final int IDX_INITIAL_JOIN_SKIP = INDEX_BUILD_OP_COUNT + PIDX_SCAN_OP_COUNT
+            + WARM_UP_SELECT_QUERY_COUNT + SELECT_QUERY_COUNT;
+    private static final int IDX_INITIAL_SELECT_SKIP = INDEX_BUILD_OP_COUNT + PIDX_SCAN_OP_COUNT
+            + WARM_UP_SELECT_QUERY_COUNT;
+
+    private static final int HYRACK_JOB_ELAPSED_TIME_FIELD = 2;
+    private static final int OP_ELAPSED_TIME_FIELD = 4;
+    private static final int OP_TASK_ID_FIELD = 2;
+    private static final int OP_NAME_FIELD = 1;
+
+    private String executionTimeFilePath = null;
+    private BufferedReader brExecutionTime;
+    private String line;
+    private int lineNum;
+
+    public OperatorProfilerReportBuilder(String executionTimeFilePath) {
+        this.executionTimeFilePath = executionTimeFilePath;
+    }
+
+    public String getIdxNumber(boolean isJoin, int radiusIdx) throws Exception {
+        openExecutionTimeFile();
+
+        StringBuilder sb = new StringBuilder();
+        int initialSkip = (isJoin ? IDX_INITIAL_JOIN_SKIP : IDX_INITIAL_SELECT_SKIP) + radiusIdx;
+        int radiusSkip = isJoin ? IDX_JOIN_RADIUS_SKIP : IDX_SELECT_RADIUS_SKIP;
+        BufferedReader br = brExecutionTime;
+        int queryCount = isJoin ? JOIN_QUERY_COUNT / JOIN_RADIUS_TYPE_COUNT : SELECT_QUERY_COUNT
+                / SELECT_RADIUS_TYPE_COUNT;
+        lineNum = 0;
+        JobStat jobStat = new JobStat();
+
+        try {
+
+            //initial skip
+            int jobCount = 0;
+            while ((line = br.readLine()) != null) {
+                lineNum++;
+                if (line.contains("TOTAL_HYRACKS_JOB")) {
+                    jobCount++;
+                    if (jobCount > initialSkip) {
+                        break;
+                    }
+                }
+            }
+
+            //Reaching Here, line variable contains the first job to be counted
+            for (int j = 0; j < queryCount; j++) {
+
+                analyzeOperatorExecutionTime(jobStat, br);
+
+                //radius skip
+                jobCount = 0;
+                while ((line = br.readLine()) != null) {
+                    lineNum++;
+                    if (line.contains("TOTAL_HYRACKS_JOB")) {
+                        jobCount++;
+                        if (jobCount > radiusSkip) {
+                            break;
+                        }
+                    }
+                }
+            }
+
+            //System.out.println("lineNum: " + lineNum);
+            sb.append("TOTAL_HYRACKS_JOB," + (((double) jobStat.getHyracksJobTimeSum()) / jobStat.getHyracksJobCount())
+                    + "," + jobStat.getHyracksJobTimeSum() + "," + jobStat.getHyracksJobCount() + "\n");
+            sb.append(jobStat.getOperatorsElapsedTimeAsString());
+            return sb.toString();
+        } finally {
+            closeExecutionTimeFile();
+        }
+    }
+
+    private void analyzeOperatorExecutionTime(JobStat jobStat, BufferedReader br) throws IOException {
+        //the line argument contains TOTAL_HYRACKS_JOB string. eg.:
+        //2015-11-04 19:13:08,003   TOTAL_HYRACKS_JOB a1_node1_JID:3_26202768 TOTAL_HYRACKS_JOB1446660788003    1066    1.066   1066    1.066
+        String tokens[] = line.split("\t");
+
+        if (Long.parseLong(tokens[HYRACK_JOB_ELAPSED_TIME_FIELD]) > 10000) {
+            System.out.println("[" + lineNum + "] " + line);
+        }
+
+        jobStat.addHyracksJobTime(Long.parseLong(tokens[HYRACK_JOB_ELAPSED_TIME_FIELD]));
+
+        while ((line = br.readLine()) != null) {
+            lineNum++;
+
+            if (line.isEmpty()) {
+                break;
+            }
+
+            tokens = line.split("\t");
+            if (line.contains("DISTRIBUTE_RESULT")) {
+                jobStat.addDistributeResultTime(Long.parseLong(tokens[OP_ELAPSED_TIME_FIELD]));
+                continue;
+            }
+            if (line.contains("EMPTY_TUPLE_SOURCE")) {
+                continue;
+            }
+
+            if (line.contains("TXN_JOB_COMMIT")) {
+                continue;
+            }
+
+            jobStat.updateOperatorTime(tokens[OP_TASK_ID_FIELD], tokens[OP_NAME_FIELD],
+                    Long.parseLong(tokens[OP_ELAPSED_TIME_FIELD]));
+        }
+
+        jobStat.updateTaskForAvgWithSlowestTask();
+    }
+
+    protected void openExecutionTimeFile() throws IOException {
+        brExecutionTime = new BufferedReader(new FileReader(executionTimeFilePath));
+    }
+
+    protected void closeExecutionTimeFile() throws IOException {
+        if (brExecutionTime != null) {
+            brExecutionTime.close();
+        }
+    }
+
+    class JobStat {
+        private long hyracksJobElapsedTimeSum;
+        private int hyracksJobCount;
+        private long distributeResultTimeSum;
+        private Task taskForAvg;
+        private HashMap<String, Task> taskId2TaskMap;
+
+        public JobStat() {
+            hyracksJobElapsedTimeSum = 0;
+            hyracksJobCount = 0;
+            distributeResultTimeSum = 0;
+            taskForAvg = new Task("TaskForAvg");
+            taskId2TaskMap = new HashMap<String, Task>();
+        }
+
+        public void reset() {
+            hyracksJobElapsedTimeSum = 0;
+            hyracksJobCount = 0;
+            distributeResultTimeSum = 0;
+            taskForAvg.reset();;
+            taskId2TaskMap.clear();
+        }
+
+        public void addHyracksJobTime(long elapsedTime) {
+            hyracksJobElapsedTimeSum += elapsedTime;
+            hyracksJobCount++;
+        }
+
+        public void addDistributeResultTime(long elapsedTime) {
+            distributeResultTimeSum += elapsedTime;
+        }
+
+        public long getDistributeResultTime() {
+            return distributeResultTimeSum;
+        }
+
+        public long getHyracksJobTimeSum() {
+            return hyracksJobElapsedTimeSum;
+        }
+
+        public int getHyracksJobCount() {
+            return hyracksJobCount;
+        }
+
+        public void updateOperatorTime(String taskId, String operatorName, long elapsedTime) {
+            Task task = taskId2TaskMap.get(taskId);
+            if (task == null) {
+                task = new Task(taskId);
+                taskId2TaskMap.put(new String(taskId), task);
+            }
+            task.updateOperatorTime(operatorName, elapsedTime);
+        }
+
+        public void updateTaskForAvgWithSlowestTask() {
+            Iterator<Entry<String, Task>> taskIter = taskId2TaskMap.entrySet().iterator();
+            Task slowestTask = null;
+            Task curTask;
+
+            //get the slowest task
+            while (taskIter.hasNext()) {
+                curTask = taskIter.next().getValue();
+                if (slowestTask == null) {
+                    slowestTask = curTask;
+                } else {
+                    if (slowestTask.getElapsedTime() < curTask.getElapsedTime()) {
+                        slowestTask = curTask;
+                    }
+                }
+            }
+
+            //update the TaskForAvg with the slowest one
+            HashMap<String, SumCount> operator2SumCountMap = slowestTask.getOperator2SumCountMap();
+            Iterator<Entry<String, SumCount>> operatorIter = operator2SumCountMap.entrySet().iterator();
+            while (operatorIter.hasNext()) {
+                Entry<String, SumCount> entry = operatorIter.next();
+                SumCount sc = entry.getValue();
+                taskForAvg.updateOperatorTime(entry.getKey(), sc.sum);
+            }
+            taskId2TaskMap.clear();
+        }
+
+        public String getOperatorsElapsedTimeAsString() {
+            return "SUM_OF_OPERATORS," + (((double) taskForAvg.getElapsedTime()) / hyracksJobCount) + ","
+                    + taskForAvg.getElapsedTime() + "," + hyracksJobCount + "\n"
+                    + taskForAvg.getOperatorsElapsedTimeAsString() + "DISTRIBUTE_RESULT,"
+                    + (((double) distributeResultTimeSum) / hyracksJobCount) + "," + distributeResultTimeSum + ","
+                    + hyracksJobCount + "\n";
+        }
+    }
+
+    class Task {
+        private String taskId;
+        private long elapsedTime;
+        private HashMap<String, SumCount> operator2SumCountMap;
+
+        public Task(String taskId) {
+            this.taskId = new String(taskId);
+            elapsedTime = 0;
+            operator2SumCountMap = new HashMap<String, SumCount>();
+        }
+
+        @Override
+        public int hashCode() {
+            return taskId.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == this) {
+                return true;
+            }
+            if (!(o instanceof Task)) {
+                return false;
+            }
+            return ((Task) o).taskId == taskId;
+        }
+
+        public long getElapsedTime() {
+            return elapsedTime;
+        }
+
+        public void updateOperatorTime(String operatorName, long elapsedTime) {
+            SumCount sc = operator2SumCountMap.get(operatorName);
+            if (sc == null) {
+                sc = new SumCount();
+                sc.sum = 0;
+                sc.count = 0;
+                operator2SumCountMap.put(new String(operatorName), sc);
+            }
+            sc.sum += elapsedTime;
+            sc.count++;
+            this.elapsedTime += elapsedTime;
+        }
+
+        public void reset() {
+            elapsedTime = 0;
+            operator2SumCountMap.clear();
+        }
+
+        public String getOperatorsElapsedTimeAsString() {
+            StringBuilder sb = new StringBuilder();
+            Iterator<Entry<String, SumCount>> iter = operator2SumCountMap.entrySet().iterator();
+            while (iter.hasNext()) {
+                Entry<String, SumCount> entry = iter.next();
+                SumCount sc = entry.getValue();
+                sb.append(entry.getKey()).append(",").append(((double) sc.sum) / sc.count).append(",").append(sc.sum)
+                        .append(",").append(sc.count).append("\n");
+            }
+            return sb.toString();
+        }
+
+        public HashMap<String, SumCount> getOperator2SumCountMap() {
+            return operator2SumCountMap;
+        }
+    }
+
+    class SumCount {
+        public long sum;
+        public int count;
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/ProfilerReportBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/ProfilerReportBuilder.java
new file mode 100644
index 0000000..d5eb539
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/ProfilerReportBuilder.java
@@ -0,0 +1,192 @@
+/*
+ * 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.asterix.experiment.report;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class ProfilerReportBuilder {
+
+    private static final int INDEX_BUILD_OP_COUNT = 1;
+    private static final int PIDX_SCAN_OP_COUNT = 1;
+    private static final int WARM_UP_SELECT_QUERY_COUNT = 500;
+    private static final int SELECT_QUERY_COUNT = 5000;
+    private static final int JOIN_QUERY_COUNT = 200;
+    private static final int PARTITION_COUNT = 4;
+
+    private static final int SELECT_QUERY_INVOLVED_INDEX_COUNT = 2;
+    private static final int JOIN_QUERY_INVOLVED_INDEX_COUNT = 3;
+    private static final int JOIN_RADIUS_TYPE_COUNT = 4;
+    private static final int SELECT_RADIUS_TYPE_COUNT = 5;
+    private static final int IDX_JOIN_RADIUS_SKIP = JOIN_RADIUS_TYPE_COUNT * JOIN_QUERY_INVOLVED_INDEX_COUNT
+            * PARTITION_COUNT - PARTITION_COUNT;
+    private static final int IDX_SELECT_RADIUS_SKIP = SELECT_RADIUS_TYPE_COUNT * SELECT_QUERY_INVOLVED_INDEX_COUNT
+            * PARTITION_COUNT - PARTITION_COUNT;
+    private static final int IDX_INITIAL_JOIN_SKIP = (INDEX_BUILD_OP_COUNT + PIDX_SCAN_OP_COUNT + ((WARM_UP_SELECT_QUERY_COUNT + SELECT_QUERY_COUNT) * SELECT_QUERY_INVOLVED_INDEX_COUNT))
+            * PARTITION_COUNT;
+    private static final int IDX_INITIAL_SELECT_SKIP = (INDEX_BUILD_OP_COUNT + PIDX_SCAN_OP_COUNT + (WARM_UP_SELECT_QUERY_COUNT * SELECT_QUERY_INVOLVED_INDEX_COUNT))
+            * PARTITION_COUNT;
+    private static final int FP_JOIN_RADIUS_SKIP = JOIN_RADIUS_TYPE_COUNT * PARTITION_COUNT - PARTITION_COUNT;
+    private static final int FP_SELECT_RADIUS_SKIP = SELECT_RADIUS_TYPE_COUNT * PARTITION_COUNT - PARTITION_COUNT;
+    private static final int FP_INITIAL_JOIN_SKIP = (PIDX_SCAN_OP_COUNT + WARM_UP_SELECT_QUERY_COUNT + SELECT_QUERY_COUNT)
+            * PARTITION_COUNT;
+    private static final int FP_INITIAL_SELECT_SKIP = (PIDX_SCAN_OP_COUNT + WARM_UP_SELECT_QUERY_COUNT)
+            * PARTITION_COUNT;
+
+    private String indexSearchTimeFilePath = null;
+    private String falsePositiveFilePath = null;
+    private String cacheMissFilePath = null;
+    private BufferedReader brIndexSearchTime;
+    private BufferedReader brFalsePositive;
+    private BufferedReader brCacheMiss;
+    private String line;
+
+    public ProfilerReportBuilder(String indexSearchTimeFilePath, String falsePositiveFilePath, String cacheMissFilePath) {
+        this.indexSearchTimeFilePath = indexSearchTimeFilePath;
+        this.falsePositiveFilePath = falsePositiveFilePath;
+        this.cacheMissFilePath = cacheMissFilePath;
+    }
+
+    public String getIdxNumber(boolean getSearchTime, boolean isJoin, int radiusIdx, int indexIdx) throws Exception {
+        if (getSearchTime) {
+            openIndexSearchTimeFile();
+        } else {
+            openCacheMissFile();
+        }
+
+        StringBuilder sb = new StringBuilder();
+        int involvedIndexCount = isJoin ? JOIN_QUERY_INVOLVED_INDEX_COUNT : SELECT_QUERY_INVOLVED_INDEX_COUNT;
+        int initialSkip = (isJoin ? IDX_INITIAL_JOIN_SKIP : IDX_INITIAL_SELECT_SKIP) + radiusIdx * involvedIndexCount
+                * PARTITION_COUNT + indexIdx * PARTITION_COUNT;
+        int radiusSkip = isJoin ? IDX_JOIN_RADIUS_SKIP : IDX_SELECT_RADIUS_SKIP;
+        long measuredValue = 0;
+        BufferedReader br = getSearchTime ? brIndexSearchTime : brCacheMiss;
+        int lineNum = 0;
+        int queryCount = isJoin ? JOIN_QUERY_COUNT / JOIN_RADIUS_TYPE_COUNT : SELECT_QUERY_COUNT
+                / SELECT_RADIUS_TYPE_COUNT;
+        try {
+
+            //initial skip
+            for (int i = 0; i < initialSkip; i++) {
+                br.readLine();
+                ++lineNum;
+            }
+
+            for (int j = 0; j < queryCount; j++) {
+                //get target index numbers
+                for (int i = 0; i < PARTITION_COUNT; i++) {
+                    line = br.readLine();
+                    measuredValue += Long.parseLong(line);
+                    ++lineNum;
+                }
+
+                //radius skip
+                for (int i = 0; i < radiusSkip; i++) {
+                    br.readLine();
+                    ++lineNum;
+                }
+            }
+
+            //System.out.println("lineNum: " + lineNum);
+            sb.append((double) measuredValue / (PARTITION_COUNT * queryCount));
+            return sb.toString();
+        } finally {
+            if (getSearchTime) {
+                closeIndexSearchTimeFile();
+            } else {
+                closeCacheMissFile();
+            }
+        }
+    }
+
+    public String getFalsePositives(boolean isJoin, int radiusIdx) throws Exception {
+        openFalsePositiveFile();
+
+        StringBuilder sb = new StringBuilder();
+        int initialSkip = (isJoin ? FP_INITIAL_JOIN_SKIP : FP_INITIAL_SELECT_SKIP) + radiusIdx * PARTITION_COUNT;
+        int radiusSkip = isJoin ? FP_JOIN_RADIUS_SKIP : FP_SELECT_RADIUS_SKIP;
+        long falsePositives = 0;
+        BufferedReader br = brFalsePositive;
+        int lineNum = 0;
+        int queryCount = isJoin ? JOIN_QUERY_COUNT / JOIN_RADIUS_TYPE_COUNT : SELECT_QUERY_COUNT
+                / SELECT_RADIUS_TYPE_COUNT;
+        try {
+
+            //initial skip
+            for (int i = 0; i < initialSkip; i++) {
+                br.readLine();
+                ++lineNum;
+            }
+
+            for (int j = 0; j < queryCount; j++) {
+                //get target index numbers
+                for (int i = 0; i < PARTITION_COUNT; i++) {
+                    line = br.readLine();
+                    falsePositives += Long.parseLong(line);
+                    ++lineNum;
+                }
+
+                //radius skip
+                for (int i = 0; i < radiusSkip; i++) {
+                    br.readLine();
+                    ++lineNum;
+                }
+            }
+
+            //System.out.println("lineNum: " + lineNum);
+            sb.append((double) falsePositives / (PARTITION_COUNT * queryCount));
+            return sb.toString();
+        } finally {
+            closeFalsePositiveFile();
+        }
+    }
+
+    protected void openIndexSearchTimeFile() throws IOException {
+        brIndexSearchTime = new BufferedReader(new FileReader(indexSearchTimeFilePath));
+    }
+
+    protected void closeIndexSearchTimeFile() throws IOException {
+        if (brIndexSearchTime != null) {
+            brIndexSearchTime.close();
+        }
+    }
+
+    protected void openFalsePositiveFile() throws IOException {
+        brFalsePositive = new BufferedReader(new FileReader(falsePositiveFilePath));
+    }
+
+    protected void closeFalsePositiveFile() throws IOException {
+        if (brFalsePositive != null) {
+            brFalsePositive.close();
+        }
+    }
+
+    protected void openCacheMissFile() throws IOException {
+        brCacheMiss = new BufferedReader(new FileReader(cacheMissFilePath));
+    }
+
+    protected void closeCacheMissFile() throws IOException {
+        if (brCacheMiss != null) {
+            brCacheMiss.close();
+        }
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/ReportBuilderHelper.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/ReportBuilderHelper.java
new file mode 100644
index 0000000..93ae819
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/ReportBuilderHelper.java
@@ -0,0 +1,104 @@
+/*
+ * 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.asterix.experiment.report;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class ReportBuilderHelper {
+
+    public static void main(String[] args) throws Exception {
+        String line = "INFO: DataGen[13][During ingestion only][TimeToInsert100000] 10651 in milliseconds";
+        System.out.println(getEndIndexOf("DataGen[1][During ingestion only][TimeToInsert100000] 10651 in milliseconds",
+                "DataGen["));
+        System.out.println(getLong(line, "[TimeToInsert100000]", "in"));
+        System.out.println(getLong(line, "DataGen[", "]"));
+        //SIE1AReportBuilder rb = new SIE1AReportBuilder("/Users/kisskys/workspace/asterix_experiment/run-log/run-log-backup/log-1435560604069/run.log");
+        //System.out.println(rb.getInstantaneousInsertPS());
+    }
+
+    public static int getEndIndexOf(String target, String pattern) {
+        //get the end index of the pattern string in target string.
+        int index = target.indexOf(pattern);
+        if (index != -1) {
+            return target.indexOf(pattern) + pattern.length();
+        }
+        return -1;
+    }
+
+    public static long getLong(String line, String beginPattern, String endPattern) {
+        int idBeginIdx = getEndIndexOf(line, beginPattern);
+        int idEndIdx = line.indexOf(endPattern, idBeginIdx);
+        return Long.parseLong(line.substring(idBeginIdx, idEndIdx).trim());
+    }
+
+    public static int getInt(String line, String beginPattern, String endPattern) {
+        int idBeginIdx = getEndIndexOf(line, beginPattern);
+        int idEndIdx = line.indexOf(endPattern, idBeginIdx);
+        return Integer.parseInt(line.substring(idBeginIdx, idEndIdx).trim());
+    }
+
+    public static double getDouble(String line, String beginPattern, String endPattern) {
+        int idBeginIdx = getEndIndexOf(line, beginPattern);
+        int idEndIdx = line.indexOf(endPattern, idBeginIdx);
+        return Double.parseDouble(line.substring(idBeginIdx, idEndIdx).trim());
+    }
+
+    public static String getString(String line, String beginPattern, String endPattern) {
+        int idBeginIdx = getEndIndexOf(line, beginPattern);
+        int idEndIdx = line.indexOf(endPattern, idBeginIdx);
+        return line.substring(idBeginIdx, idEndIdx).trim();
+    }
+    
+    public static String getString(String line, String endPattern) {
+        int idEndIdx = line.indexOf(endPattern, 0);
+        return line.substring(0, idEndIdx).trim();
+    }
+
+    public static long getTimeStampAsLong(String line, SimpleDateFormat format) throws ParseException {
+        //Jul 09, 2015 11:58:08
+        //String line = "Jul 09, 2015 11:58:09 PM org.apache.hyracks.storage.am.lsm.common.impls.LSMHarness flush";
+        //DateFormat format;
+        //format = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss");
+        Date parseDate = format.parse(line);
+        return parseDate.getTime();
+    }
+    
+    protected static FileOutputStream openOutputFile(String filepath) throws IOException {
+        File file = new File(filepath);
+        if (file.exists()) {
+            //throw new IOException(filepath + "already exists");
+            file.delete();
+        }
+        file.createNewFile();
+        return new FileOutputStream(file);
+    }
+
+    protected static void closeOutputFile(FileOutputStream fos) throws IOException {
+        fos.flush();
+        fos.close();
+        fos = null;
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/ReportBuilderRunner.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/ReportBuilderRunner.java
new file mode 100644
index 0000000..eba8f07
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/ReportBuilderRunner.java
@@ -0,0 +1,126 @@
+/*
+ * 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.asterix.experiment.report;
+
+public class ReportBuilderRunner {
+    public static final boolean REPORT_SIE1 = false;
+    public static final boolean REPORT_SIE2 = false;
+    public static final boolean REPORT_SIE3 = false;
+    public static final boolean REPORT_SIE4 = false;
+    public static final boolean REPORT_SIE5 = true;
+    public static final boolean REPORT_SIE3_PROFILE = false;
+
+    public static void main(String[] args) throws Exception {
+
+        if (REPORT_SIE1) {
+            SIE1ReportBuilderRunner sie1 = new SIE1ReportBuilderRunner();
+            sie1.generateSIE1IPS();
+            //        sie1.generateInstantaneousInsertPS();
+            sie1.generateIndexSize();
+            sie1.generateGanttInstantaneousInsertPS();
+            sie1.generateAccumulatedInsertPS();
+        }
+
+        if (REPORT_SIE2) {
+            SIE2ReportBuilderRunner sie2 = new SIE2ReportBuilderRunner();
+            sie2.generateOverallInsertPS();
+            sie2.generateAccumulatedInsertPS();
+            sie2.generateQueryPS();
+            sie2.generateAverageQueryResultCount();
+            sie2.generateAverageQueryResponseTime();
+            sie2.generateInstantaneousInsertPS();
+            sie2.generateGanttInstantaneousInsertPS();
+            sie2.generateSelectQueryResponseTime();
+            sie2.generateSelectQueryResultCount();
+        }
+
+        if (REPORT_SIE3) {
+            SIE3ReportBuilderRunner sie3 = new SIE3ReportBuilderRunner();
+            sie3.generateIndexCreationTime();
+            sie3.generateIndexSize();
+            sie3.generateSelectQueryResponseTime();
+            sie3.generateJoinQueryResponseTime();
+            sie3.generateSelectQueryResultCount();
+            sie3.generateJoinQueryResultCount();
+
+            //            sie3.generateSelectQueryProfiledSidxSearchTime();
+            //            sie3.generateSelectQueryProfiledPidxSearchTime();
+            //            sie3.generateJoinQueryProfiledSidxSearchTime();
+            //            sie3.generateJoinQueryProfiledPidxSearchTime();
+            //            sie3.generateJoinQueryProfiledSeedPidxSearchTime();
+            //            sie3.generateSelectQueryProfiledSidxCacheMiss();
+            //            sie3.generateSelectQueryProfiledPidxCacheMiss();
+            //            sie3.generateJoinQueryProfiledSidxCacheMiss();
+            //            sie3.generateJoinQueryProfiledPidxCacheMiss();
+            //            sie3.generateJoinQueryProfiledSeedPidxCacheMiss();
+            //            sie3.generateSelectQueryProfiledFalsePositive();
+            //            sie3.generateJoinQueryProfiledFalsePositive();
+        }
+
+        if (REPORT_SIE4) {
+            SIE4ReportBuilderRunner sie4 = new SIE4ReportBuilderRunner();
+            sie4.generateIndexCreationTime();
+            sie4.generateIndexSize();
+            sie4.generateSelectQueryResponseTime();
+            sie4.generateJoinQueryResponseTime();
+            sie4.generateSelectQueryResultCount();
+            sie4.generateJoinQueryResultCount();
+        }
+
+        if (REPORT_SIE5) {
+            SIE5ReportBuilderRunner sie5 = new SIE5ReportBuilderRunner();
+            sie5.generateOverallInsertPS();
+            sie5.generateAccumulatedInsertPS();
+            sie5.generateQueryPS();
+            sie5.generateAverageQueryResultCount();
+            sie5.generateAverageQueryResponseTime();
+            sie5.generateInstantaneousInsertPS();
+            sie5.generateGanttInstantaneousInsertPS();
+            sie5.generateSelectQueryResponseTime();
+            sie5.generateSelectQueryResultCount();
+        }
+
+        if (REPORT_SIE3_PROFILE) {
+            String executionTimeFilePath[] = new String[5];
+            executionTimeFilePath[0] = "/Users/kisskys/workspace/asterix_master/resultLog/Mem3g-Disk4g-part4-Lsev-Jvm5g-Lock6g/profile-exp3/SpatialIndexExperiment3Dhbtree/logs/executionTime-130.149.249.52.txt";
+            executionTimeFilePath[1] = "/Users/kisskys/workspace/asterix_master/resultLog/Mem3g-Disk4g-part4-Lsev-Jvm5g-Lock6g/profile-exp3/SpatialIndexExperiment3Dhvbtree/logs/executionTime-130.149.249.52.txt";
+            executionTimeFilePath[2] = "/Users/kisskys/workspace/asterix_master/resultLog/Mem3g-Disk4g-part4-Lsev-Jvm5g-Lock6g/profile-exp3/SpatialIndexExperiment3Rtree/logs/executionTime-130.149.249.52.txt";
+            executionTimeFilePath[3] = "/Users/kisskys/workspace/asterix_master/resultLog/Mem3g-Disk4g-part4-Lsev-Jvm5g-Lock6g/profile-exp3/SpatialIndexExperiment3Shbtree/logs/executionTime-130.149.249.52.txt";
+            executionTimeFilePath[4] = "/Users/kisskys/workspace/asterix_master/resultLog/Mem3g-Disk4g-part4-Lsev-Jvm5g-Lock6g/profile-exp3/SpatialIndexExperiment3Sif/logs/executionTime-130.149.249.52.txt";
+
+            for (int i = 0; i < 5; i++) {
+                String filePath = executionTimeFilePath[i];
+                OperatorProfilerReportBuilder oprb = new OperatorProfilerReportBuilder(filePath);
+                System.out.println("--------  " + i + " ----------\n");
+                System.out.println(oprb.getIdxNumber(false, 0));
+                System.out.println(oprb.getIdxNumber(false, 1));
+                System.out.println(oprb.getIdxNumber(false, 2));
+                System.out.println(oprb.getIdxNumber(false, 3));
+                System.out.println(oprb.getIdxNumber(false, 4));
+                System.out.println(oprb.getIdxNumber(true, 0));
+                System.out.println(oprb.getIdxNumber(true, 1));
+                System.out.println(oprb.getIdxNumber(true, 2));
+                System.out.println(oprb.getIdxNumber(true, 3));
+            }
+
+        }
+
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE1ReportBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE1ReportBuilder.java
new file mode 100644
index 0000000..2e04615
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE1ReportBuilder.java
@@ -0,0 +1,69 @@
+/*
+ * 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.asterix.experiment.report;
+
+public class SIE1ReportBuilder extends AbstractDynamicDataEvalReportBuilder {
+    public SIE1ReportBuilder(String expHomePath, String expName, String runLogFileName) {
+        super(expHomePath, expName, runLogFileName, false);
+    }
+
+    @Override
+    public String getOverallInsertPS(int minutes) throws Exception {
+        renewStringBuilder();
+        openRunLog();
+        try {
+            if (!moveToExperimentBegin()) {
+                //The experiment run log doesn't exist in this run log file
+                return null;
+            }
+
+            String line;
+            while ((line = br.readLine()) != null) {
+                if (line.contains("int64")) {
+                    line = br.readLine();
+                    rsb.append(Long.parseLong(line) / (minutes * 60));
+                    break;
+                }
+            }
+
+            return rsb.toString();
+        } finally {
+            closeRunLog();
+        }
+    }
+
+    @Override
+    public String getInstantaneousQueryPS() throws Exception {
+        return null;
+    }
+
+    @Override
+    public String getQueryPS(int minutes) throws Exception {
+        return null;
+        //        renewStringBuilder();
+        //        openRunLog();
+        //        try {
+        //
+        //            return getResult();
+        //        } finally {
+        //            closeRunLog();
+        //        }
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE1ReportBuilderRunner.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE1ReportBuilderRunner.java
new file mode 100644
index 0000000..bab69a0
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE1ReportBuilderRunner.java
@@ -0,0 +1,329 @@
+/*
+ * 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.asterix.experiment.report;
+
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+
+public class SIE1ReportBuilderRunner {
+    String expHomePath = "/Users/kisskys/workspace/asterix_master/resultLog/MemBuf3g-DiskBuf3g-Lsev-Jvm7g-Lock0g/exp1/";
+    String runLogFileName = "run-exp1.log";
+    String outputFilePath = "/Users/kisskys/workspace/asterix_master/resultLog/MemBuf3g-DiskBuf3g-Lsev-Jvm7g-Lock0g/result-report/";
+
+    SIE1ReportBuilder sie1ADhbtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1ADhbtree",
+            runLogFileName);
+    SIE1ReportBuilder sie1ADhvbtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1ADhvbtree",
+            runLogFileName);
+    SIE1ReportBuilder sie1ARtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1ARtree", runLogFileName);
+    SIE1ReportBuilder sie1AShbtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1AShbtree",
+            runLogFileName);
+    SIE1ReportBuilder sie1ASif = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1ASif", runLogFileName);
+
+    SIE1ReportBuilder sie1BDhbtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1BDhbtree",
+            runLogFileName);
+    SIE1ReportBuilder sie1BDhvbtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1BDhvbtree",
+            runLogFileName);
+    SIE1ReportBuilder sie1BRtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1BRtree", runLogFileName);
+    SIE1ReportBuilder sie1BShbtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1BShbtree",
+            runLogFileName);
+    SIE1ReportBuilder sie1BSif = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1BSif", runLogFileName);
+
+    SIE1ReportBuilder sie1CDhbtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1CDhbtree",
+            runLogFileName);
+    SIE1ReportBuilder sie1CDhvbtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1CDhvbtree",
+            runLogFileName);
+    SIE1ReportBuilder sie1CRtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1CRtree", runLogFileName);
+    SIE1ReportBuilder sie1CShbtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1CShbtree",
+            runLogFileName);
+    SIE1ReportBuilder sie1CSif = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1CSif", runLogFileName);
+
+    SIE1ReportBuilder sie1DDhbtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1DDhbtree",
+            runLogFileName);
+    SIE1ReportBuilder sie1DDhvbtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1DDhvbtree",
+            runLogFileName);
+    SIE1ReportBuilder sie1DRtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1DRtree", runLogFileName);
+    SIE1ReportBuilder sie1DShbtree = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1DShbtree",
+            runLogFileName);
+    SIE1ReportBuilder sie1DSif = new SIE1ReportBuilder(expHomePath, "SpatialIndexExperiment1DSif", runLogFileName);
+
+    StringBuilder sb = new StringBuilder();
+
+    /**
+     * generate sie1_ips.txt
+     */
+    public void generateSIE1IPS() throws Exception {
+        int minutes = 60;
+        sb.setLength(0);
+        sb.append("# sie1 ips(inserts per second) report\n");
+        sb.append("# number of nodes, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("1,").append(sie1ADhbtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1ADhvbtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1ARtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1AShbtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1ASif.getOverallInsertPS(minutes)).append("\n");
+
+        sb.append("2,").append(sie1BDhbtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1BDhvbtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1BRtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1BShbtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1BSif.getOverallInsertPS(minutes)).append("\n");
+
+        sb.append("4,").append(sie1CDhbtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1CDhvbtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1CRtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1CShbtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1CSif.getOverallInsertPS(minutes)).append("\n");
+
+        sb.append("8,").append(sie1DDhbtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1DDhvbtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1DRtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1DShbtree.getOverallInsertPS(minutes)).append(",")
+                .append(sie1DSif.getOverallInsertPS(minutes)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie1_ips.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    /**
+     * generate sie1_accumulated_insert_ps.txt
+     */
+    public void generateAccumulatedInsertPS() throws Exception {
+        int targetRound = 721; //(3600 seconds / 5seconds) + 1
+        int roundInterval = 5;
+
+        ArrayList<Long> ipsListDhbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListDhvbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListRtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListShbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListSif = new ArrayList<Long>();
+        sie1DDhbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListDhbtree);
+        sie1DDhvbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListDhvbtree);
+        sie1DRtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListRtree);
+        sie1DShbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListShbtree);
+        sie1DSif.getAllNodesAccumulatedInsertPS(targetRound, ipsListSif);
+
+        sb.setLength(0);
+        sb.append("# sie1 accumulated inserts per second report\n");
+        sb.append("# time, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+
+        for (int i = 0; i < targetRound; i++) {
+            sb.append("" + (i * roundInterval) + "," + ipsListDhbtree.get(i) + "," + ipsListDhvbtree.get(i) + ","
+                    + ipsListRtree.get(i) + "," + ipsListShbtree.get(i) + "," + ipsListSif.get(i) + "\n");
+        }
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie1_accumulated_insert_ps.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        ipsListDhbtree.clear();
+        ipsListDhvbtree.clear();
+        ipsListRtree.clear();
+        ipsListShbtree.clear();
+        ipsListSif.clear();
+    }
+
+    public void generateInstantaneousInsertPS() throws Exception {
+        int nodeCount = 8;
+        for (int i = 0; i < nodeCount; i++) {
+            sb.setLength(0);
+            sb.append("# sie1 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie1DDhbtree.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie1_8nodes_instantaneous_insert_ps_dhbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < nodeCount; i++) {
+            sb.setLength(0);
+            sb.append("# sie1 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie1DDhvbtree.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie1_8nodes_instantaneous_insert_ps_dhvbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < nodeCount; i++) {
+            sb.setLength(0);
+            sb.append("# sie1 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie1DRtree.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie1_8nodes_instantaneous_insert_ps_rtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < nodeCount; i++) {
+            sb.setLength(0);
+            sb.append("# sie1 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie1DShbtree.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie1_8nodes_instantaneous_insert_ps_shbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < nodeCount; i++) {
+            sb.setLength(0);
+            sb.append("# sie1 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie1DSif.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie1_8nodes_instantaneous_insert_ps_sif_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+    }
+
+    public void generateIndexSize() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie1 index size report\n");
+
+        sb.append("# number of nodes, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("1,").append(sie1ADhbtree.getIndexSize("Tweets_idx_dhbtreeLocation/device_id")).append(",")
+                .append(sie1ADhvbtree.getIndexSize("Tweets_idx_dhvbtreeLocation/device_id")).append(",")
+                .append(sie1ARtree.getIndexSize("Tweets_idx_rtreeLocation/device_id")).append(",")
+                .append(sie1AShbtree.getIndexSize("Tweets_idx_shbtreeLocation/device_id")).append(",")
+                .append(sie1ASif.getIndexSize("Tweets_idx_sifLocation/device_id")).append(",")
+                .append(sie1ASif.getIndexSize("Tweets_idx_Tweets/device_id")).append("\n");
+        sb.append("2,").append(sie1BDhbtree.getIndexSize("Tweets_idx_dhbtreeLocation/device_id")).append(",")
+                .append(sie1BDhvbtree.getIndexSize("Tweets_idx_dhvbtreeLocation/device_id")).append(",")
+                .append(sie1BRtree.getIndexSize("Tweets_idx_rtreeLocation/device_id")).append(",")
+                .append(sie1BShbtree.getIndexSize("Tweets_idx_shbtreeLocation/device_id")).append(",")
+                .append(sie1BSif.getIndexSize("Tweets_idx_sifLocation/device_id")).append(",")
+                .append(sie1BSif.getIndexSize("Tweets_idx_Tweets/device_id")).append("\n");
+        sb.append("4,").append(sie1CDhbtree.getIndexSize("Tweets_idx_dhbtreeLocation/device_id")).append(",")
+                .append(sie1CDhvbtree.getIndexSize("Tweets_idx_dhvbtreeLocation/device_id")).append(",")
+                .append(sie1CRtree.getIndexSize("Tweets_idx_rtreeLocation/device_id")).append(",")
+                .append(sie1CShbtree.getIndexSize("Tweets_idx_shbtreeLocation/device_id")).append(",")
+                .append(sie1CSif.getIndexSize("Tweets_idx_sifLocation/device_id")).append(",")
+                .append(sie1CSif.getIndexSize("Tweets_idx_Tweets/device_id")).append("\n");
+        sb.append("8,").append(sie1DDhbtree.getIndexSize("Tweets_idx_dhbtreeLocation/device_id")).append(",")
+                .append(sie1DDhvbtree.getIndexSize("Tweets_idx_dhvbtreeLocation/device_id")).append(",")
+                .append(sie1DRtree.getIndexSize("Tweets_idx_rtreeLocation/device_id")).append(",")
+                .append(sie1DShbtree.getIndexSize("Tweets_idx_shbtreeLocation/device_id")).append(",")
+                .append(sie1DSif.getIndexSize("Tweets_idx_sifLocation/device_id")).append(",")
+                .append(sie1DSif.getIndexSize("Tweets_idx_Tweets/device_id")).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie1_index_size.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateGanttInstantaneousInsertPS() throws Exception {
+
+        SIE1ReportBuilder dhbtree = sie1DDhbtree;
+        SIE1ReportBuilder dhvbtree = sie1DDhvbtree;
+        SIE1ReportBuilder rtree = sie1DRtree;
+        SIE1ReportBuilder shbtree = sie1DShbtree;
+        SIE1ReportBuilder sif = sie1DSif;
+        String sie1Type = "D";
+        String logDirPrefix = "";
+
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie1 1node(1 dataGen) instantaneous inserts per second report\n");
+            sb.append(dhbtree.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie1_gantt_1node_instantaneous_insert_ps_dhbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie1 1node(1 dataGen) instantaneous inserts per second report\n");
+            sb.append(dhvbtree.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie1_gantt_1node_instantaneous_insert_ps_dhvbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie1 1node(1 dataGen) instantaneous inserts per second report\n");
+            sb.append(rtree.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie1_gantt_1node_instantaneous_insert_ps_rtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie1 1node(1 dataGen) instantaneous inserts per second report\n");
+            sb.append(shbtree.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie1_gantt_1node_instantaneous_insert_ps_shbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie1 1node(1 dataGen) instantaneous inserts per second report\n");
+            sb.append(sif.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie1_gantt_1node_instantaneous_insert_ps_sif_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+
+        long dataGenStartTime = dhbtree.getDataGenStartTimeStamp();
+        NCLogReportBuilder ncLogReportBuilder = new NCLogReportBuilder(expHomePath + "SpatialIndexExperiment1"
+                + sie1Type + "Dhbtree/" + logDirPrefix + "logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie1_gantt_1node_flush_merge_dhbtree.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        dataGenStartTime = dhvbtree.getDataGenStartTimeStamp();
+        ncLogReportBuilder = new NCLogReportBuilder(expHomePath + "SpatialIndexExperiment1" + sie1Type + "Dhvbtree/"
+                + logDirPrefix + "logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie1_gantt_1node_flush_merge_dhvbtree.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        dataGenStartTime = rtree.getDataGenStartTimeStamp();
+        ncLogReportBuilder = new NCLogReportBuilder(expHomePath + "SpatialIndexExperiment1" + sie1Type + "Rtree/"
+                + logDirPrefix + "logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie1_gantt_1node_flush_merge_rtree.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        dataGenStartTime = shbtree.getDataGenStartTimeStamp();
+        ncLogReportBuilder = new NCLogReportBuilder(expHomePath + "SpatialIndexExperiment1" + sie1Type + "Shbtree/"
+                + logDirPrefix + "logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie1_gantt_1node_flush_merge_shbtree.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        dataGenStartTime = sif.getDataGenStartTimeStamp();
+        ncLogReportBuilder = new NCLogReportBuilder(expHomePath + "SpatialIndexExperiment1" + sie1Type + "Sif/"
+                + logDirPrefix + "logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie1_gantt_1node_flush_merge_sif.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE2ReportBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE2ReportBuilder.java
new file mode 100644
index 0000000..52034a4
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE2ReportBuilder.java
@@ -0,0 +1,264 @@
+/*
+ * 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.asterix.experiment.report;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class SIE2ReportBuilder extends AbstractDynamicDataEvalReportBuilder {
+    private static final int SELECT_QUERY_RADIUS_COUNT = 5;
+    private static final int INITIAL_SELECT_QUERY_COUNT_TO_IGNORE = 0;
+    private static final int MAX_SELECT_QUERY_COUNT_TO_CONSIDER = Integer.MAX_VALUE; //5000 + INITIAL_SELECT_QUERY_COUNT_TO_CONSIDER;
+    private static final int QUERY_GEN_COUNT = 8;
+    private static final String[] QUERY_GEN_IPS = { "130.149.249.61", "130.149.249.62", "130.149.249.63",
+            "130.149.249.64", "130.149.249.65", "130.149.249.66", "130.149.249.67", "130.149.249.68" };
+    private BufferedReader[] queryLogFileBrs;
+
+    public SIE2ReportBuilder(String expHomePath, String expName, String runLogFileName) {
+        super(expHomePath, expName, runLogFileName, false);
+        queryLogFileBrs = new BufferedReader[QUERY_GEN_COUNT];
+    }
+
+    @Override
+    public String getOverallInsertPS(int minutes) throws Exception {
+        return null;
+    }
+
+    public String get20minInsertPS(int minutes) throws Exception {
+        renewStringBuilder();
+        openRunLog();
+        try {
+            if (!moveToExperimentBegin()) {
+                //The experiment run log doesn't exist in this run log file
+                return null;
+            }
+
+            String line;
+            long insertCount = 0;
+            while ((line = br.readLine()) != null) {
+                if (line.contains("[During ingestion + queries][InsertCount]")) {
+                    insertCount += ReportBuilderHelper.getLong(line, "=", "in");
+                }
+                if (line.contains("Running")) {
+                    break;
+                }
+            }
+            rsb.append(insertCount / (minutes * 60));
+            return rsb.toString();
+        } finally {
+            closeRunLog();
+        }
+    }
+
+    public double getFirstXminInsertPS(int minutes, int genId, int unitMinutes) throws Exception {
+        renewStringBuilder();
+        openRunLog();
+        try {
+            if (!moveToExperimentBegin()) {
+                //The experiment run log doesn't exist in this run log file
+                return 0;
+            }
+
+            String line;
+            int dGenId;
+            int count = 0;
+            long timeToInsert = 0;
+            long totalTimeToInsert = 0;
+            boolean haveResult = false;
+            while ((line = br.readLine()) != null) {
+                if (line.contains("[During ingestion only][TimeToInsert100000]")) {
+                    dGenId = ReportBuilderHelper.getInt(line, "DataGen[", "]");
+                    if (dGenId == genId) {
+                        count++;
+                        timeToInsert = ReportBuilderHelper.getLong(line, INSTANTANEOUS_INSERT_STRING, "in");
+                        totalTimeToInsert += timeToInsert;
+                        if (totalTimeToInsert > minutes * 60000) {
+                            haveResult = true;
+                            break;
+                        }
+                    }
+                }
+                if (line.contains("Running")) {
+                    break;
+                }
+            }
+            if (haveResult || totalTimeToInsert > (minutes * 60000 - unitMinutes * 60000)) {
+                return (count * INSTANTAEOUS_INSERT_COUNT) / ((double) totalTimeToInsert / 1000);
+            } else {
+                return 0;
+                //return  ((count * INSTANTAEOUS_INSERT_COUNT) / ((double)totalTimeToInsert/1000)) * -1;
+            }
+        } finally {
+            closeRunLog();
+        }
+    }
+
+    @Override
+    public String getInstantaneousQueryPS() throws Exception {
+        return null;
+    }
+
+    @Override
+    public String getQueryPS(int minutes) throws Exception {
+        renewStringBuilder();
+        openRunLog();
+        try {
+            if (!moveToExperimentBegin()) {
+                //The experiment run log doesn't exist in this run log file
+                return null;
+            }
+
+            String line;
+            long queryCount = 0;
+            while ((line = br.readLine()) != null) {
+                if (line.contains("[QueryCount]")) {
+                    queryCount += ReportBuilderHelper.getLong(line, "[QueryCount]", "in");
+                }
+                if (line.contains("Running")) {
+                    break;
+                }
+            }
+            rsb.append(queryCount / (float) (minutes * 60));
+            return rsb.toString();
+        } finally {
+            closeRunLog();
+        }
+    }
+
+    public String getAverageQueryResultCount() throws Exception {
+        renewStringBuilder();
+        openQueryLog();
+        try {
+            String line;
+            long resultCount = 0;
+            long queryCount = 0;
+            for (BufferedReader queryLogFileBr : queryLogFileBrs) {
+                while ((line = queryLogFileBr.readLine()) != null) {
+                    if (line.contains("int64")) {
+                        line = queryLogFileBr.readLine();
+                        resultCount += Long.parseLong(line);
+                        ++queryCount;
+                    }
+                }
+            }
+            rsb.append(resultCount / queryCount);
+            return rsb.toString();
+        } finally {
+            closeQueryLog();
+        }
+    }
+
+    public String getAverageQueryResponseTime() throws Exception {
+        renewStringBuilder();
+        openQueryLog();
+        try {
+            String line;
+            long responseTime = 0;
+            long queryCount = 0;
+            for (BufferedReader queryLogFileBr : queryLogFileBrs) {
+                while ((line = queryLogFileBr.readLine()) != null) {
+                    if (line.contains("Elapsed time = ")) {
+                        responseTime += ReportBuilderHelper.getLong(line, "=", "for");
+                        ++queryCount;
+                    }
+                }
+            }
+            rsb.append(responseTime / queryCount);
+            return rsb.toString();
+        } finally {
+            closeQueryLog();
+        }
+    }
+
+    public String getSelectQueryResponseTime(int radiusIdx) throws Exception {
+        renewStringBuilder();
+        openQueryLog();
+        try {
+            String line;
+            long queryResponseTime = 0;
+            int targetRadiusSelectQueryCount = 0;
+            for (BufferedReader queryLogFileBr : queryLogFileBrs) {
+                int selectQueryCount = 0;
+                while ((line = queryLogFileBr.readLine()) != null) {
+                    if (line.contains("Elapsed time =") && selectQueryCount < MAX_SELECT_QUERY_COUNT_TO_CONSIDER) {
+                        if (selectQueryCount % SELECT_QUERY_RADIUS_COUNT == radiusIdx
+                                && selectQueryCount >= INITIAL_SELECT_QUERY_COUNT_TO_IGNORE) {
+                            queryResponseTime += ReportBuilderHelper.getLong(line, "=", "for");
+                            ++targetRadiusSelectQueryCount;
+                        }
+                        ++selectQueryCount;
+                    }
+                }
+            }
+            rsb.append((double) queryResponseTime / targetRadiusSelectQueryCount);
+            return rsb.toString();
+        } finally {
+            closeQueryLog();
+        }
+    }
+
+    public String getSelectQueryResultCount(int radiusIdx) throws Exception {
+        renewStringBuilder();
+        openQueryLog();
+        try {
+            String line;
+            long queryResultCount = 0;
+            int targetRadiusSelectQueryCount = 0;
+            for (BufferedReader queryLogFileBr : queryLogFileBrs) {
+                int selectQueryCount = 0;
+                while ((line = queryLogFileBr.readLine()) != null) {
+                    if (line.contains("int64") && selectQueryCount < MAX_SELECT_QUERY_COUNT_TO_CONSIDER) {
+                        if (selectQueryCount % SELECT_QUERY_RADIUS_COUNT == radiusIdx
+                                && selectQueryCount >= INITIAL_SELECT_QUERY_COUNT_TO_IGNORE) {
+                            line = queryLogFileBr.readLine(); //read the result count line
+                            queryResultCount += Long.parseLong(line);
+                            ++targetRadiusSelectQueryCount;
+                        }
+                        ++selectQueryCount;
+                    }
+                }
+            }
+            rsb.append((double) queryResultCount / targetRadiusSelectQueryCount);
+            return rsb.toString();
+        } finally {
+            closeQueryLog();
+        }
+    }
+
+    private void openQueryLog() throws IOException {
+        String queryLogFilePathPrefix = expHomePath + File.separator + expName + File.separator + "QueryGenResult-";
+        String queryLogFilePathSuffix = ".txt";
+        for (int i = 0; i < QUERY_GEN_COUNT; i++) {
+            queryLogFileBrs[i] = new BufferedReader(new FileReader(queryLogFilePathPrefix + QUERY_GEN_IPS[i]
+                    + queryLogFilePathSuffix));
+        }
+    }
+
+    private void closeQueryLog() throws IOException {
+        for (BufferedReader queryLogFileBr : queryLogFileBrs) {
+            if (queryLogFileBr != null) {
+                queryLogFileBr.close();
+                queryLogFileBr = null;
+            }
+        }
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE2ReportBuilderRunner.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE2ReportBuilderRunner.java
new file mode 100644
index 0000000..91f30f5
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE2ReportBuilderRunner.java
@@ -0,0 +1,459 @@
+/*
+ * 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.asterix.experiment.report;
+
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+
+public class SIE2ReportBuilderRunner {
+    String expHomePath = "/Users/kisskys/workspace/asterix_master/resultLog/MemBuf3g-DiskBuf3g-Lsev-Jvm7g-Lock0g/exp2-4/";
+    String runLogFileName = "run-exp2-4.log";
+    String outputFilePath = "/Users/kisskys/workspace/asterix_master/resultLog/MemBuf3g-DiskBuf3g-Lsev-Jvm7g-Lock0g/result-report/";
+
+    SIE2ReportBuilder sie2Dhbtree = new SIE2ReportBuilder(expHomePath, "SpatialIndexExperiment2Dhbtree", runLogFileName);
+    SIE2ReportBuilder sie2Dhvbtree = new SIE2ReportBuilder(expHomePath, "SpatialIndexExperiment2Dhvbtree",
+            runLogFileName);
+    SIE2ReportBuilder sie2Rtree = new SIE2ReportBuilder(expHomePath, "SpatialIndexExperiment2Rtree", runLogFileName);
+    SIE2ReportBuilder sie2Shbtree = new SIE2ReportBuilder(expHomePath, "SpatialIndexExperiment2Shbtree", runLogFileName);
+    SIE2ReportBuilder sie2Sif = new SIE2ReportBuilder(expHomePath, "SpatialIndexExperiment2Sif", runLogFileName);
+
+    StringBuilder sb = new StringBuilder();
+
+    /**
+     * generate sie2_overall_insert_ps.txt
+     */
+    public void generateOverallInsertPS() throws Exception {
+        int targetRound = 721; //(3600 seconds / 5seconds) + 1
+
+        ArrayList<Long> ipsListDhbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListDhvbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListRtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListShbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListSif = new ArrayList<Long>();
+        sie2Dhbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListDhbtree);
+        sie2Dhvbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListDhvbtree);
+        sie2Rtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListRtree);
+        sie2Shbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListShbtree);
+        sie2Sif.getAllNodesAccumulatedInsertPS(targetRound, ipsListSif);
+
+        sb.setLength(0);
+        sb.append("# sie2 60min inserts per second report\n");
+        sb.append("index type, InsertPS\n");
+        sb.append("dhbtree,").append(ipsListDhbtree.get(targetRound - 1)).append("\n");
+        sb.append("dhvbtree,").append(ipsListDhvbtree.get(targetRound - 1)).append("\n");
+        sb.append("rtree,").append(ipsListRtree.get(targetRound - 1)).append("\n");
+        sb.append("shbtree,").append(ipsListShbtree.get(targetRound - 1)).append("\n");
+        sb.append("sif,").append(ipsListSif.get(targetRound - 1)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie2_overall_insert_ps.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        ipsListDhbtree.clear();
+        ipsListDhvbtree.clear();
+        ipsListRtree.clear();
+        ipsListShbtree.clear();
+        ipsListSif.clear();
+    }
+
+    /**
+     * generate sie2_accumulated_insert_ps.txt
+     */
+    public void generateAccumulatedInsertPS() throws Exception {
+        int targetRound = 721; //(3600 seconds / 5seconds) + 1
+        int roundInterval = 5;
+
+        ArrayList<Long> ipsListDhbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListDhvbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListRtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListShbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListSif = new ArrayList<Long>();
+        sie2Dhbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListDhbtree);
+        sie2Dhvbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListDhvbtree);
+        sie2Rtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListRtree);
+        sie2Shbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListShbtree);
+        sie2Sif.getAllNodesAccumulatedInsertPS(targetRound, ipsListSif);
+
+        sb.setLength(0);
+        sb.append("# sie2 accumulated inserts per second report\n");
+        sb.append("# time, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+
+        for (int i = 0; i < targetRound; i++) {
+            sb.append("" + (i * roundInterval) + "," + ipsListDhbtree.get(i) + "," + ipsListDhvbtree.get(i) + ","
+                    + ipsListRtree.get(i) + "," + ipsListShbtree.get(i) + "," + ipsListSif.get(i) + "\n");
+        }
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie2_accumulated_insert_ps.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        ipsListDhbtree.clear();
+        ipsListDhvbtree.clear();
+        ipsListRtree.clear();
+        ipsListShbtree.clear();
+        ipsListSif.clear();
+    }
+
+    public void generateQueryPS() throws Exception {
+        int minutes = 60;
+        sb.setLength(0);
+        sb.append("# sie2 queries per second report\n");
+        sb.append("index type, QueryPS\n");
+        sb.append("dhbtree,").append(sie2Dhbtree.getQueryPS(minutes)).append("\n");
+        sb.append("dhvbtree,").append(sie2Dhvbtree.getQueryPS(minutes)).append("\n");
+        sb.append("rtree,").append(sie2Rtree.getQueryPS(minutes)).append("\n");
+        sb.append("shbtree,").append(sie2Shbtree.getQueryPS(minutes)).append("\n");
+        sb.append("sif,").append(sie2Sif.getQueryPS(minutes)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie2_query_ps.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateAverageQueryResultCount() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie2 average query result count report\n");
+        sb.append("index type, query result count\n");
+        sb.append("dhbtree,").append(sie2Dhbtree.getAverageQueryResultCount()).append("\n");
+        sb.append("dhvbtree,").append(sie2Dhvbtree.getAverageQueryResultCount()).append("\n");
+        sb.append("rtree,").append(sie2Rtree.getAverageQueryResultCount()).append("\n");
+        sb.append("shbtree,").append(sie2Shbtree.getAverageQueryResultCount()).append("\n");
+        sb.append("sif,").append(sie2Sif.getAverageQueryResultCount()).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie2_average_query_result_count.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateAverageQueryResponseTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie2 average query response time report\n");
+        sb.append("index type, query response time\n");
+        sb.append("dhbtree,").append(sie2Dhbtree.getAverageQueryResponseTime()).append("\n");
+        sb.append("dhvbtree,").append(sie2Dhvbtree.getAverageQueryResponseTime()).append("\n");
+        sb.append("rtree,").append(sie2Rtree.getAverageQueryResponseTime()).append("\n");
+        sb.append("shbtree,").append(sie2Shbtree.getAverageQueryResponseTime()).append("\n");
+        sb.append("sif,").append(sie2Sif.getAverageQueryResponseTime()).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie2_average_query_response_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateInstantaneousInsertPS() throws Exception {
+        for (int i = 0; i < 8; i++) {
+            sb.setLength(0);
+            sb.append("# sie2 instantaneous inserts per second report\n");
+            sb.append(sie2Dhbtree.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie2_instantaneous_insert_ps_dhbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 8; i++) {
+            sb.setLength(0);
+            sb.append("# sie2 instantaneous inserts per second report\n");
+            sb.append(sie2Dhvbtree.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie2_instantaneous_insert_ps_dhvbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 8; i++) {
+            sb.setLength(0);
+            sb.append("# sie2 instantaneous inserts per second report\n");
+            sb.append(sie2Rtree.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie2_instantaneous_insert_ps_rtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 8; i++) {
+            sb.setLength(0);
+            sb.append("# sie2 instantaneous inserts per second report\n");
+            sb.append(sie2Shbtree.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie2_instantaneous_insert_ps_shbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 8; i++) {
+            sb.setLength(0);
+            sb.append("# sie2 instantaneous inserts per second report\n");
+            sb.append(sie2Sif.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie2_instantaneous_insert_ps_sif_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+    }
+
+    public void generateGanttInstantaneousInsertPS() throws Exception {
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie2 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie2Dhbtree.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie2_gantt_1node_instantaneous_insert_ps_dhbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie2 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie2Dhvbtree.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie2_gantt_1node_instantaneous_insert_ps_dhvbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie2 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie2Rtree.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie2_gantt_1node_instantaneous_insert_ps_rtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie2 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie2Shbtree.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie2_gantt_1node_instantaneous_insert_ps_shbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie2 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie2Sif.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie2_gantt_1node_instantaneous_insert_ps_sif_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+
+        long dataGenStartTime = sie2Dhbtree.getDataGenStartTimeStamp();
+        NCLogReportBuilder ncLogReportBuilder = new NCLogReportBuilder(expHomePath
+                + "SpatialIndexExperiment2Dhbtree/logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie2_gantt_1node_flush_merge_dhbtree.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        dataGenStartTime = sie2Dhvbtree.getDataGenStartTimeStamp();
+        ncLogReportBuilder = new NCLogReportBuilder(expHomePath + "SpatialIndexExperiment2Dhvbtree/logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie2_gantt_1node_flush_merge_dhvbtree.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        dataGenStartTime = sie2Rtree.getDataGenStartTimeStamp();
+        ncLogReportBuilder = new NCLogReportBuilder(expHomePath + "SpatialIndexExperiment2Rtree/logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie2_gantt_1node_flush_merge_rtree.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        dataGenStartTime = sie2Shbtree.getDataGenStartTimeStamp();
+        ncLogReportBuilder = new NCLogReportBuilder(expHomePath + "SpatialIndexExperiment2Shbtree/logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie2_gantt_1node_flush_merge_shbtree.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        dataGenStartTime = sie2Sif.getDataGenStartTimeStamp();
+        ncLogReportBuilder = new NCLogReportBuilder(expHomePath + "SpatialIndexExperiment2Sif/logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie2_gantt_1node_flush_merge_sif.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryResponseTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie2 select query response time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie2Dhbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie2Rtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie2Shbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie2Sif.getSelectQueryResponseTime(0)).append("\n");
+        sb.append("0.0001,").append(sie2Dhbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie2Rtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie2Shbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie2Sif.getSelectQueryResponseTime(1)).append("\n");
+        sb.append("0.001,").append(sie2Dhbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie2Rtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie2Shbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie2Sif.getSelectQueryResponseTime(2)).append("\n");
+        sb.append("0.01,").append(sie2Dhbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie2Rtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie2Shbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie2Sif.getSelectQueryResponseTime(3)).append("\n");
+        sb.append("0.1,").append(sie2Dhbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie2Rtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie2Shbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie2Sif.getSelectQueryResponseTime(4)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie2_select_query_response_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        sb.setLength(0);
+        sb.append("# sie2 select query response time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie2Dhbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie2Rtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie2Shbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie2Sif.getSelectQueryResponseTime(0)).append("\n");
+        sb.append("0.0001,").append(sie2Dhbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie2Rtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie2Shbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie2Sif.getSelectQueryResponseTime(1)).append("\n");
+        sb.append("0.001,").append(sie2Dhbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie2Rtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie2Shbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie2Sif.getSelectQueryResponseTime(2)).append("\n");
+
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie2_select_query_response_time1.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        sb.setLength(0);
+        sb.append("# sie2 select query response time 2 report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.01,").append(sie2Dhbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie2Rtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie2Shbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie2Sif.getSelectQueryResponseTime(3)).append("\n");
+        sb.append("0.1,").append(sie2Dhbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie2Rtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie2Shbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie2Sif.getSelectQueryResponseTime(4)).append("\n");
+
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie2_select_query_response_time2.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryResultCount() throws Exception {
+
+        sb.setLength(0);
+        sb.append("# sie2 select query result count report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie2Dhbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie2Rtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie2Shbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie2Sif.getSelectQueryResultCount(0)).append("\n");
+        sb.append("0.0001,").append(sie2Dhbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie2Rtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie2Shbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie2Sif.getSelectQueryResultCount(1)).append("\n");
+        sb.append("0.001,").append(sie2Dhbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie2Rtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie2Shbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie2Sif.getSelectQueryResultCount(2)).append("\n");
+        sb.append("0.01,").append(sie2Dhbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie2Rtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie2Shbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie2Sif.getSelectQueryResultCount(3)).append("\n");
+        sb.append("0.1,").append(sie2Dhbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie2Rtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie2Shbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie2Sif.getSelectQueryResultCount(4)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper
+                .openOutputFile(outputFilePath + "sie2_select_query_result_count.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        sb.setLength(0);
+        sb.append("# sie2 select query result count 1 report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie2Dhbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie2Rtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie2Shbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie2Sif.getSelectQueryResultCount(0)).append("\n");
+        sb.append("0.0001,").append(sie2Dhbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie2Rtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie2Shbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie2Sif.getSelectQueryResultCount(1)).append("\n");
+        sb.append("0.001,").append(sie2Dhbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie2Rtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie2Shbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie2Sif.getSelectQueryResultCount(2)).append("\n");
+
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie2_select_query_result_count1.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        sb.setLength(0);
+        sb.append("# sie2 select query result count 2 report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.01,").append(sie2Dhbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie2Rtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie2Shbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie2Sif.getSelectQueryResultCount(3)).append("\n");
+        sb.append("0.1,").append(sie2Dhbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie2Dhvbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie2Rtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie2Shbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie2Sif.getSelectQueryResultCount(4)).append("\n");
+
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie2_select_query_result_count2.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE3ProfileReportBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE3ProfileReportBuilder.java
new file mode 100644
index 0000000..138afb4
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE3ProfileReportBuilder.java
@@ -0,0 +1,69 @@
+/*
+ * 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.asterix.experiment.report;
+
+public class SIE3ProfileReportBuilder extends AbstractDynamicDataEvalReportBuilder {
+    public SIE3ProfileReportBuilder(String expHomePath, String expName, String runLogFileName) {
+        super(expHomePath, expName, runLogFileName, false);
+    }
+
+    @Override
+    public String getOverallInsertPS(int minutes) throws Exception {
+        renewStringBuilder();
+        openRunLog();
+        try {
+            if (!moveToExperimentBegin()) {
+                //The experiment run log doesn't exist in this run log file
+                return null;
+            }
+
+            String line;
+            while ((line = br.readLine()) != null) {
+                if (line.contains("int64")) {
+                    line = br.readLine();
+                    rsb.append(Long.parseLong(line) / (minutes * 60));
+                    break;
+                }
+            }
+
+            return rsb.toString();
+        } finally {
+            closeRunLog();
+        }
+    }
+
+    @Override
+    public String getInstantaneousQueryPS() throws Exception {
+        return null;
+    }
+
+    @Override
+    public String getQueryPS(int minutes) throws Exception {
+        return null;
+        //        renewStringBuilder();
+        //        openRunLog();
+        //        try {
+        //
+        //            return getResult();
+        //        } finally {
+        //            closeRunLog();
+        //        }
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE3ReportBuilder.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE3ReportBuilder.java
new file mode 100644
index 0000000..0f36b2a
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE3ReportBuilder.java
@@ -0,0 +1,294 @@
+/*
+ * 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.asterix.experiment.report;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class SIE3ReportBuilder extends AbstractDynamicDataEvalReportBuilder {
+    private static final int WARM_UP_QUERY_COUNT = 500;
+    private static final int SELECT_QUERY_COUNT = 5000; //5000
+    private static final int JOIN_QUERY_COUNT = 1000;
+    private static final int SELECT_QUERY_RADIUS_COUNT = 5; //0.00001, 0.0001, 0.001, 0.01, 0.1
+    private static final int JOIN_QUERY_RADIUS_COUNT = 4; ////0.00001, 0.0001, 0.001, 0.01
+    private static final String LOADED_RECORD_COUNT = "1600000000"; //1600000000
+    private final String queryLogFilePath;
+    private BufferedReader queryLogFileBr;
+
+    public SIE3ReportBuilder(String expHomePath, String expName, String runLogFileName, String queryLogFileName) {
+        super(expHomePath, expName, runLogFileName, false);
+        queryLogFilePath = new String(expHomePath + File.separator + expName + File.separator + queryLogFileName);
+    }
+
+    private void openQueryLog() throws IOException {
+        queryLogFileBr = new BufferedReader(new FileReader(queryLogFilePath));
+    }
+
+    private void closeQueryLog() throws IOException {
+        if (queryLogFileBr != null) {
+            queryLogFileBr.close();
+            queryLogFileBr = null;
+        }
+    }
+
+    @Override
+    public String getOverallInsertPS(int minutes) throws Exception {
+        return null;
+    }
+
+    public String get20minInsertPS(int minutes) throws Exception {
+        return null;
+    }
+
+    @Override
+    public String getInstantaneousQueryPS() throws Exception {
+        return null;
+    }
+
+    @Override
+    public String getQueryPS(int minutes) throws Exception {
+        return null;
+    }
+
+    public String getIndexCreationTime() throws Exception {
+        renewStringBuilder();
+        openQueryLog();
+
+        try {
+            String line;
+            long indexCreationTime = 0;
+            while ((line = queryLogFileBr.readLine()) != null) {
+                if (line.contains("There is no index with this name")) {
+                    indexCreationTime += ReportBuilderHelper.getLong(line, "=", "for");
+                    break;
+                }
+            }
+            rsb.append((double) indexCreationTime / (1000 * 60));
+            return rsb.toString();
+        } finally {
+            closeQueryLog();
+        }
+    }
+
+    public String getSelectQueryResponseTime(int radiusIdx) throws Exception {
+        renewStringBuilder();
+        openQueryLog();
+        try {
+            String line;
+            long queryResponseTime = 0;
+            int selectQueryCount = 0;
+            int targetRadiusSelectQueryCount = 0;
+            while ((line = queryLogFileBr.readLine()) != null) {
+                if (line.contains(LOADED_RECORD_COUNT)) {
+                    //select queries start after total count query
+                    // read and discard WARM_UP_QUERY_COUNT queries' results 
+                    while (true) {
+                        line = queryLogFileBr.readLine();
+                        if (line.contains("Elapsed time =")) {
+                            ++selectQueryCount;
+                        }
+                        if (selectQueryCount == WARM_UP_QUERY_COUNT) {
+                            break;
+                        }
+                    }
+
+                    // read and calculate the average query response time for the requested(target) radius
+                    while (true) {
+                        line = queryLogFileBr.readLine();
+                        if (line.contains("Elapsed time =")) {
+                            if (selectQueryCount % SELECT_QUERY_RADIUS_COUNT == radiusIdx) {
+                                queryResponseTime += ReportBuilderHelper.getLong(line, "=", "for");
+                                ++targetRadiusSelectQueryCount;
+                            }
+                            ++selectQueryCount;
+                        }
+                        if (selectQueryCount == WARM_UP_QUERY_COUNT + SELECT_QUERY_COUNT) {
+                            break;
+                        }
+                    }
+                    break;
+                }
+            }
+            rsb.append((double) queryResponseTime / targetRadiusSelectQueryCount);
+            return rsb.toString();
+        } finally {
+            closeQueryLog();
+        }
+    }
+
+    public String getSelectQueryResultCount(int radiusIdx) throws Exception {
+        renewStringBuilder();
+        openQueryLog();
+        try {
+
+            String line;
+            long queryResultCount = 0;
+            int selectQueryCount = 0;
+            int targetRadiusSelectQueryCount = 0;
+            while ((line = queryLogFileBr.readLine()) != null) {
+                if (line.contains(LOADED_RECORD_COUNT)) {
+                    //select queries start after total count query
+                    // read and discard WARM_UP_QUERY_COUNT queries' results 
+                    while (true) {
+                        line = queryLogFileBr.readLine();
+                        if (line.contains("int64")) {
+                            ++selectQueryCount;
+                        }
+                        if (selectQueryCount == WARM_UP_QUERY_COUNT) {
+                            break;
+                        }
+                    }
+
+                    // read and calculate the average query response time for the requested(target) radius
+                    while (true) {
+                        line = queryLogFileBr.readLine();
+                        if (line.contains("int64")) {
+                            if (selectQueryCount % SELECT_QUERY_RADIUS_COUNT == radiusIdx) {
+                                line = queryLogFileBr.readLine();
+                                queryResultCount += Long.parseLong(line);
+                                ++targetRadiusSelectQueryCount;
+                            }
+                            ++selectQueryCount;
+                        }
+                        if (selectQueryCount == WARM_UP_QUERY_COUNT + SELECT_QUERY_COUNT) {
+                            break;
+                        }
+                    }
+                    break;
+                }
+            }
+            rsb.append((double) queryResultCount / targetRadiusSelectQueryCount);
+            return rsb.toString();
+        } finally {
+            closeQueryLog();
+        }
+    }
+
+    public String getJoinQueryResponseTime(int radiusIdx) throws Exception {
+        renewStringBuilder();
+        openQueryLog();
+        try {
+
+            String line;
+            long queryResponseTime = 0;
+            int selectQueryCount = 0;
+            int targetRadiusJoinQueryCount = 0;
+            while ((line = queryLogFileBr.readLine()) != null) {
+                if (line.contains(LOADED_RECORD_COUNT)) {
+                    //select queries start after total count query
+                    // read and discard WARM_UP_QUERY_COUNT + SELECT_QUERY_COUNT queries' results 
+                    while (true) {
+                        line = queryLogFileBr.readLine();
+                        if (line.contains("Elapsed time =")) {
+                            ++selectQueryCount;
+                        }
+                        if (selectQueryCount == WARM_UP_QUERY_COUNT + SELECT_QUERY_COUNT) {
+                            break;
+                        }
+                    }
+
+                    selectQueryCount = 0;
+                    // read and calculate the average query response time for the requested(target) radius
+                    while (true) {
+                        line = queryLogFileBr.readLine();
+                        if (line.contains("Elapsed time =")) {
+                            if (selectQueryCount % JOIN_QUERY_RADIUS_COUNT == radiusIdx) {
+                                if (ReportBuilderHelper.getLong(line, "=", "for") > 5000) {
+                                    System.out.println("Time: " + expName + "[" + radiusIdx + ", "
+                                            + targetRadiusJoinQueryCount + ", " + selectQueryCount + "]:"
+                                            + ReportBuilderHelper.getLong(line, "=", "for"));
+                                }
+                                queryResponseTime += ReportBuilderHelper.getLong(line, "=", "for");
+                                ++targetRadiusJoinQueryCount;
+                            }
+                            ++selectQueryCount;
+                        }
+                        if (selectQueryCount == JOIN_QUERY_COUNT) {
+                            break;
+                        }
+                    }
+                    break;
+                }
+            }
+            rsb.append((double) queryResponseTime / targetRadiusJoinQueryCount);
+            return rsb.toString();
+        } finally {
+            closeQueryLog();
+        }
+    }
+
+    public String getJoinQueryResultCount(int radiusIdx) throws Exception {
+        renewStringBuilder();
+        openQueryLog();
+        try {
+
+            String line;
+            long queryResultCount = 0;
+            int selectQueryCount = 0;
+            int targetRadiusJoinQueryCount = 0;
+            while ((line = queryLogFileBr.readLine()) != null) {
+                if (line.contains(LOADED_RECORD_COUNT)) {
+                    //select queries start after total count query
+                    // read and discard WARM_UP_QUERY_COUNT + SELECT_QUERY_COUNT queries' results 
+                    while (true) {
+                        line = queryLogFileBr.readLine();
+                        if (line.contains("int64")) {
+                            ++selectQueryCount;
+                        }
+                        if (selectQueryCount == WARM_UP_QUERY_COUNT + SELECT_QUERY_COUNT) {
+                            break;
+                        }
+                    }
+
+                    selectQueryCount = 0;
+                    // read and calculate the average query response time for the requested(target) radius
+                    while (true) {
+                        line = queryLogFileBr.readLine();
+                        if (line.contains("int64")) {
+                            if (selectQueryCount % JOIN_QUERY_RADIUS_COUNT == radiusIdx) {
+                                line = queryLogFileBr.readLine();
+
+                                if (selectQueryCount == 600 || selectQueryCount == 824 || Long.parseLong(line) > 100000) {
+                                    System.out.println("Count: " + expName + "[" + radiusIdx + ", "
+                                            + targetRadiusJoinQueryCount + ", " + selectQueryCount + "]:"
+                                            + Long.parseLong(line));
+                                }
+
+                                queryResultCount += Long.parseLong(line);
+                                ++targetRadiusJoinQueryCount;
+                            }
+                            ++selectQueryCount;
+                        }
+                        if (selectQueryCount == JOIN_QUERY_COUNT) {
+                            break;
+                        }
+                    }
+                    break;
+                }
+            }
+            rsb.append((double) queryResultCount / targetRadiusJoinQueryCount);
+            return rsb.toString();
+        } finally {
+            closeQueryLog();
+        }
+    }
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE3ReportBuilderRunner.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE3ReportBuilderRunner.java
new file mode 100644
index 0000000..8cfff8b
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE3ReportBuilderRunner.java
@@ -0,0 +1,716 @@
+/*
+ * 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.asterix.experiment.report;
+
+import java.io.BufferedReader;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class SIE3ReportBuilderRunner {
+    static boolean IS_PROFILE = false;
+    String outputFilePath = "/Users/kisskys/workspace/asterix_master/resultLog/MemBuf3g-DiskBuf3g-Lsev-Jvm7g-Lock0g/result-report/";
+    SIE3ReportBuilder sie3Dhbtree;
+    SIE3ReportBuilder sie3Dhvbtree;
+    SIE3ReportBuilder sie3Rtree;
+    SIE3ReportBuilder sie3Shbtree;
+    SIE3ReportBuilder sie3Sif;
+
+    //for profiling report -------------------------------------
+    String profileFileHomeDir;
+    String indexSearchTimeFilePath;
+    String falsePositiveFilePath;
+    String cacheMissFilePath;
+    ProfilerReportBuilder dhbtreeProfiler;
+    ProfilerReportBuilder dhvbtreeProfiler;
+    ProfilerReportBuilder rtreeProfiler;
+    ProfilerReportBuilder shbtreeProfiler;
+    ProfilerReportBuilder sifProfiler;
+    //for profiling report -------------------------------------
+
+    StringBuilder sb = new StringBuilder();
+
+    public SIE3ReportBuilderRunner() {
+
+        String expHomePath = "/Users/kisskys/workspace/asterix_master/resultLog/MemBuf3g-DiskBuf3g-Lsev-Jvm7g-Lock0g/exp3/";
+        String runLogFileName = "run-exp3.log";
+        String queryLogFileNamePrefix = "QueryGenResult-";
+        String queryLogFileNameSuffix = "-130.149.249.51.txt";
+
+        sie3Dhbtree = new SIE3ReportBuilder(expHomePath, "SpatialIndexExperiment3Dhbtree", runLogFileName,
+                queryLogFileNamePrefix + "SpatialIndexExperiment3Dhbtree" + queryLogFileNameSuffix);
+        sie3Dhvbtree = new SIE3ReportBuilder(expHomePath, "SpatialIndexExperiment3Dhvbtree", runLogFileName,
+                queryLogFileNamePrefix + "SpatialIndexExperiment3Dhvbtree" + queryLogFileNameSuffix);
+        sie3Rtree = new SIE3ReportBuilder(expHomePath, "SpatialIndexExperiment3Rtree", runLogFileName,
+                queryLogFileNamePrefix + "SpatialIndexExperiment3Rtree" + queryLogFileNameSuffix);
+        sie3Shbtree = new SIE3ReportBuilder(expHomePath, "SpatialIndexExperiment3Shbtree", runLogFileName,
+                queryLogFileNamePrefix + "SpatialIndexExperiment3Shbtree" + queryLogFileNameSuffix);
+        sie3Sif = new SIE3ReportBuilder(expHomePath, "SpatialIndexExperiment3Sif", runLogFileName,
+                queryLogFileNamePrefix + "SpatialIndexExperiment3Sif" + queryLogFileNameSuffix);
+    }
+
+    public void generateIndexCreationTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 index creation time report\n");
+        sb.append("index type, index creation time\n");
+        sb.append("dhbtree,").append(sie3Dhbtree.getIndexCreationTime()).append("\n");
+        sb.append("dhvbtree,").append(sie3Dhvbtree.getIndexCreationTime()).append("\n");
+        sb.append("rtree,").append(sie3Rtree.getIndexCreationTime()).append("\n");
+        sb.append("shbtree,").append(sie3Shbtree.getIndexCreationTime()).append("\n");
+        sb.append("sif,").append(sie3Sif.getIndexCreationTime()).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie3_index_creation_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateIndexSize() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 index size report\n");
+
+        sb.append("index type, index size\n");
+        sb.append("dhbtree,").append(sie3Dhbtree.getIndexSize("Tweets_idx_dhbtreeLocation/device_id")).append("\n");
+        sb.append("dhvbtree,").append(sie3Dhvbtree.getIndexSize("Tweets_idx_dhvbtreeLocation/device_id")).append("\n");
+        sb.append("rtree,").append(sie3Rtree.getIndexSize("Tweets_idx_rtreeLocation/device_id")).append("\n");
+        sb.append("shbtree,").append(sie3Shbtree.getIndexSize("Tweets_idx_shbtreeLocation/device_id")).append("\n");
+        sb.append("sif,").append(sie3Sif.getIndexSize("Tweets_idx_sifLocation/device_id")).append("\n");
+        sb.append("# pidx,").append(sie3Sif.getIndexSize("Tweets_idx_Tweets/device_id")).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie3_sidx_size.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryResponseTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 select query response time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie3Dhbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie3Dhvbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie3Rtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie3Shbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie3Sif.getSelectQueryResponseTime(0)).append("\n");
+        sb.append("0.0001,").append(sie3Dhbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie3Dhvbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie3Rtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie3Shbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie3Sif.getSelectQueryResponseTime(1)).append("\n");
+        sb.append("0.001,").append(sie3Dhbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie3Dhvbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie3Rtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie3Shbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie3Sif.getSelectQueryResponseTime(2)).append("\n");
+        sb.append("0.01,").append(sie3Dhbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie3Dhvbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie3Rtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie3Shbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie3Sif.getSelectQueryResponseTime(3)).append("\n");
+        sb.append("0.1,").append(sie3Dhbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie3Dhvbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie3Rtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie3Shbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie3Sif.getSelectQueryResponseTime(4)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie3_select_query_response_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryResultCount() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 select query result count report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie3Dhbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie3Dhvbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie3Rtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie3Shbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie3Sif.getSelectQueryResultCount(0)).append("\n");
+        sb.append("0.0001,").append(sie3Dhbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie3Dhvbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie3Rtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie3Shbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie3Sif.getSelectQueryResultCount(1)).append("\n");
+        sb.append("0.001,").append(sie3Dhbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie3Dhvbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie3Rtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie3Shbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie3Sif.getSelectQueryResultCount(2)).append("\n");
+        sb.append("0.01,").append(sie3Dhbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie3Dhvbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie3Rtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie3Shbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie3Sif.getSelectQueryResultCount(3)).append("\n");
+        sb.append("0.1,").append(sie3Dhbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie3Dhvbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie3Rtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie3Shbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie3Sif.getSelectQueryResultCount(4)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper
+                .openOutputFile(outputFilePath + "sie3_select_query_result_count.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryResponseTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 join query response time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie3Dhbtree.getJoinQueryResponseTime(0)).append(",")
+                .append(sie3Dhvbtree.getJoinQueryResponseTime(0)).append(",")
+                .append(sie3Rtree.getJoinQueryResponseTime(0)).append(",")
+                .append(sie3Shbtree.getJoinQueryResponseTime(0)).append(",")
+                .append(sie3Sif.getJoinQueryResponseTime(0)).append("\n");
+        sb.append("0.0001,").append(sie3Dhbtree.getJoinQueryResponseTime(1)).append(",")
+                .append(sie3Dhvbtree.getJoinQueryResponseTime(1)).append(",")
+                .append(sie3Rtree.getJoinQueryResponseTime(1)).append(",")
+                .append(sie3Shbtree.getJoinQueryResponseTime(1)).append(",")
+                .append(sie3Sif.getJoinQueryResponseTime(1)).append("\n");
+        sb.append("0.001,").append(sie3Dhbtree.getJoinQueryResponseTime(2)).append(",")
+                .append(sie3Dhvbtree.getJoinQueryResponseTime(2)).append(",")
+                .append(sie3Rtree.getJoinQueryResponseTime(2)).append(",")
+                .append(sie3Shbtree.getJoinQueryResponseTime(2)).append(",")
+                .append(sie3Sif.getJoinQueryResponseTime(2)).append("\n");
+        sb.append("0.01,").append(sie3Dhbtree.getJoinQueryResponseTime(3)).append(",")
+                .append(sie3Dhvbtree.getJoinQueryResponseTime(3)).append(",")
+                .append(sie3Rtree.getJoinQueryResponseTime(3)).append(",")
+                .append(sie3Shbtree.getJoinQueryResponseTime(3)).append(",")
+                .append(sie3Sif.getJoinQueryResponseTime(3)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie3_join_query_response_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryResultCount() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 join query result count report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie3Dhbtree.getJoinQueryResultCount(0)).append(",")
+                .append(sie3Dhvbtree.getJoinQueryResultCount(0)).append(",")
+                .append(sie3Rtree.getJoinQueryResultCount(0)).append(",")
+                .append(sie3Shbtree.getJoinQueryResultCount(0)).append(",").append(sie3Sif.getJoinQueryResultCount(0))
+                .append("\n");
+        sb.append("0.0001,").append(sie3Dhbtree.getJoinQueryResultCount(1)).append(",")
+                .append(sie3Dhvbtree.getJoinQueryResultCount(1)).append(",")
+                .append(sie3Rtree.getJoinQueryResultCount(1)).append(",")
+                .append(sie3Shbtree.getJoinQueryResultCount(1)).append(",").append(sie3Sif.getJoinQueryResultCount(1))
+                .append("\n");
+        sb.append("0.001,").append(sie3Dhbtree.getJoinQueryResultCount(2)).append(",")
+                .append(sie3Dhvbtree.getJoinQueryResultCount(2)).append(",")
+                .append(sie3Rtree.getJoinQueryResultCount(2)).append(",")
+                .append(sie3Shbtree.getJoinQueryResultCount(2)).append(",").append(sie3Sif.getJoinQueryResultCount(2))
+                .append("\n");
+        sb.append("0.01,").append(sie3Dhbtree.getJoinQueryResultCount(3)).append(",")
+                .append(sie3Dhvbtree.getJoinQueryResultCount(3)).append(",")
+                .append(sie3Rtree.getJoinQueryResultCount(3)).append(",")
+                .append(sie3Shbtree.getJoinQueryResultCount(3)).append(",").append(sie3Sif.getJoinQueryResultCount(3))
+                .append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie3_join_query_result_count.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryProfiledSidxSearchTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 select query profiled sidx search time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(true, false, 0, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 0, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 0, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 0, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 0, 0)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(true, false, 1, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 1, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 1, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 1, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 1, 0)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(true, false, 2, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 2, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 2, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 2, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 2, 0)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(true, false, 3, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 3, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 3, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 3, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 3, 0)).append("\n");
+        sb.append("0.1,").append(dhbtreeProfiler.getIdxNumber(true, false, 4, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 4, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 4, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 4, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 4, 0)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie3_select_query_profiled_sidx_search_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryProfiledPidxSearchTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 select query profiled pidx search time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(true, false, 0, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 0, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 0, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 0, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 0, 1)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(true, false, 1, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 1, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 1, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 1, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 1, 1)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(true, false, 2, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 2, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 2, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 2, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 2, 1)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(true, false, 3, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 3, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 3, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 3, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 3, 1)).append("\n");
+        sb.append("0.1,").append(dhbtreeProfiler.getIdxNumber(true, false, 4, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 4, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 4, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 4, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 4, 1)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie3_select_query_profiled_pidx_search_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledSidxSearchTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 join query profiled sidx search time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(true, true, 0, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 0, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 0, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 0, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 0, 1)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(true, true, 1, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 1, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 1, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 1, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 1, 1)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(true, true, 2, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 2, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 2, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 2, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 2, 1)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(true, true, 3, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 3, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 3, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 3, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 3, 1)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie3_join_query_profiled_sidx_search_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledPidxSearchTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 join query profiled pidx search time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(true, true, 0, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 0, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 0, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 0, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 0, 2)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(true, true, 1, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 1, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 1, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 1, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 1, 2)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(true, true, 2, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 2, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 2, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 2, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 2, 2)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(true, true, 3, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 3, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 3, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 3, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 3, 2)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie3_join_query_profiled_pidx_search_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledSeedPidxSearchTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 join query profiled query seed pidx search time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(true, true, 0, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 0, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 0, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 0, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 0, 0)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(true, true, 1, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 1, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 1, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 1, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 1, 0)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(true, true, 2, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 2, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 2, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 2, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 2, 0)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(true, true, 3, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 3, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 3, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 3, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 3, 0)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie3_join_query_profiled_seed_pidx_search_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryProfiledSidxCacheMiss() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 select query profiled sidx cache miss report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(false, false, 0, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 0, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 0, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 0, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 0, 0)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(false, false, 1, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 1, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 1, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 1, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 1, 0)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(false, false, 2, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 2, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 2, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 2, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 2, 0)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(false, false, 3, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 3, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 3, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 3, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 3, 0)).append("\n");
+        sb.append("0.1,").append(dhbtreeProfiler.getIdxNumber(false, false, 4, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 4, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 4, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 4, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 4, 0)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie3_select_query_profiled_sidx_cache_miss.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryProfiledPidxCacheMiss() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 select query profiled pidx cache miss report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(false, false, 0, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 0, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 0, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 0, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 0, 1)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(false, false, 1, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 1, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 1, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 1, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 1, 1)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(false, false, 2, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 2, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 2, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 2, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 2, 1)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(false, false, 3, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 3, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 3, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 3, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 3, 1)).append("\n");
+        sb.append("0.1,").append(dhbtreeProfiler.getIdxNumber(false, false, 4, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 4, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 4, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 4, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 4, 1)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie3_select_query_profiled_pidx_cache_miss.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledSidxCacheMiss() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 join query profiled sidx cache miss report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(false, true, 0, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 0, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 0, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 0, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 0, 1)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(false, true, 1, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 1, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 1, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 1, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 1, 1)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(false, true, 2, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 2, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 2, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 2, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 2, 1)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(false, true, 3, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 3, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 3, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 3, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 3, 1)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie3_join_query_profiled_sidx_cache_miss.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledPidxCacheMiss() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 join query profiled pidx cache miss report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(false, true, 0, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 0, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 0, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 0, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 0, 2)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(false, true, 1, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 1, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 1, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 1, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 1, 2)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(false, true, 2, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 2, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 2, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 2, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 2, 2)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(false, true, 3, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 3, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 3, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 3, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 3, 2)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie3_join_query_profiled_pidx_cache_miss.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledSeedPidxCacheMiss() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 join query profiled query seed pidx search time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(false, true, 0, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 0, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 0, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 0, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 0, 0)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(false, true, 1, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 1, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 1, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 1, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 1, 0)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(false, true, 2, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 2, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 2, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 2, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 2, 0)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(false, true, 3, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 3, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 3, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 3, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 3, 0)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie3_join_query_profiled_seed_pidx_cache_miss.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryProfiledFalsePositive() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 select query profiled false positive raw report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getFalsePositives(false, 0)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(false, 0)).append(",")
+                .append(rtreeProfiler.getFalsePositives(false, 0)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(false, 0)).append(",")
+                .append(sifProfiler.getFalsePositives(false, 0)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getFalsePositives(false, 1)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(false, 1)).append(",")
+                .append(rtreeProfiler.getFalsePositives(false, 1)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(false, 1)).append(",")
+                .append(sifProfiler.getFalsePositives(false, 1)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getFalsePositives(false, 2)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(false, 2)).append(",")
+                .append(rtreeProfiler.getFalsePositives(false, 2)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(false, 2)).append(",")
+                .append(sifProfiler.getFalsePositives(false, 2)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getFalsePositives(false, 3)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(false, 3)).append(",")
+                .append(rtreeProfiler.getFalsePositives(false, 3)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(false, 3)).append(",")
+                .append(sifProfiler.getFalsePositives(false, 3)).append("\n");
+        sb.append("0.1,").append(dhbtreeProfiler.getFalsePositives(false, 4)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(false, 4)).append(",")
+                .append(rtreeProfiler.getFalsePositives(false, 4)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(false, 4)).append(",")
+                .append(sifProfiler.getFalsePositives(false, 4)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie3_select_query_profiled_false_positive_raw.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+        generateFalsePositive(outputFilePath + "sie3_select_query_profiled_false_positive_raw.txt", outputFilePath
+                + "sie3_select_query_result_count.txt", outputFilePath
+                + "sie3_select_query_profiled_false_positive.txt", false);
+    }
+
+    private void generateFalsePositive(String falsePositveFile, String queryResultCountFile, String outputFile,
+            boolean isJoin) throws IOException {
+
+        String[] fps, rcs;
+        sb.setLength(0);
+
+        BufferedReader brFalsePositive = new BufferedReader(new FileReader(falsePositveFile));
+        BufferedReader brQueryResultCount = new BufferedReader(new FileReader(queryResultCountFile));
+
+        //discard two head lines
+        brFalsePositive.readLine();
+        brFalsePositive.readLine();
+        brQueryResultCount.readLine();
+        brQueryResultCount.readLine();
+
+        int radiusCount = isJoin ? 4 : 5;
+        int partitionCount = 24;
+        String[] radius = { "0.00001", "0.0001", "0.001", "0.01", "0.1" };
+
+        if (isJoin) {
+            sb.append("# sie3 join query profiled false positive report\n");
+        } else {
+            sb.append("# sie3 select query profiled false positive report\n");
+        }
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+
+        for (int i = 0; i < radiusCount; i++) {
+            fps = brFalsePositive.readLine().split(",");
+            rcs = brQueryResultCount.readLine().split(",");
+            //false positive count
+            sb.append(radius[i])
+                    .append(",")
+                    .append(((Double.parseDouble(fps[1]) * partitionCount) - Double.parseDouble(rcs[1]))
+                            / partitionCount)
+                    .append(",")
+                    .append(((Double.parseDouble(fps[2]) * partitionCount) - Double.parseDouble(rcs[2]))
+                            / partitionCount)
+                    .append(",")
+                    .append(((Double.parseDouble(fps[3]) * partitionCount) - Double.parseDouble(rcs[3]))
+                            / partitionCount)
+                    .append(",")
+                    .append(((Double.parseDouble(fps[4]) * partitionCount) - Double.parseDouble(rcs[4]))
+                            / partitionCount)
+                    .append(",")
+                    .append(((Double.parseDouble(fps[5]) * partitionCount) - Double.parseDouble(rcs[5]))
+                            / partitionCount).append("\n");
+            //false positive rate
+            //            sb.append(radius[i])
+            //            .append(",").append(((Double.parseDouble(fps[1]) * partitionCount) - Double.parseDouble(rcs[1]))/(Double.parseDouble(fps[1]) * partitionCount))
+            //            .append(",").append(((Double.parseDouble(fps[2]) * partitionCount) - Double.parseDouble(rcs[2]))/(Double.parseDouble(fps[2]) * partitionCount))
+            //            .append(",").append(((Double.parseDouble(fps[3]) * partitionCount) - Double.parseDouble(rcs[3]))/(Double.parseDouble(fps[3]) * partitionCount))
+            //            .append(",").append(((Double.parseDouble(fps[4]) * partitionCount) - Double.parseDouble(rcs[4]))/(Double.parseDouble(fps[4]) * partitionCount))
+            //            .append(",").append(((Double.parseDouble(fps[5]) * partitionCount) - Double.parseDouble(rcs[5]))/(Double.parseDouble(fps[5]) * partitionCount))
+            //            .append("\n");
+        }
+        brFalsePositive.close();
+        brQueryResultCount.close();
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFile);
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledFalsePositive() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie3 join query profiled false positive raw report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getFalsePositives(true, 0)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(true, 0)).append(",")
+                .append(rtreeProfiler.getFalsePositives(true, 0)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(true, 0)).append(",")
+                .append(sifProfiler.getFalsePositives(true, 0)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getFalsePositives(true, 1)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(true, 1)).append(",")
+                .append(rtreeProfiler.getFalsePositives(true, 1)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(true, 1)).append(",")
+                .append(sifProfiler.getFalsePositives(true, 1)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getFalsePositives(true, 2)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(true, 2)).append(",")
+                .append(rtreeProfiler.getFalsePositives(true, 2)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(true, 2)).append(",")
+                .append(sifProfiler.getFalsePositives(true, 2)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getFalsePositives(true, 3)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(true, 3)).append(",")
+                .append(rtreeProfiler.getFalsePositives(true, 3)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(true, 3)).append(",")
+                .append(sifProfiler.getFalsePositives(true, 3)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie3_join_query_profiled_false_positive_raw.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        generateFalsePositive(outputFilePath + "sie3_join_query_profiled_false_positive_raw.txt", outputFilePath
+                + "sie3_join_query_result_count.txt", outputFilePath + "sie3_join_query_profiled_false_positive.txt",
+                true);
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE4ReportBuilderRunner.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE4ReportBuilderRunner.java
new file mode 100644
index 0000000..2dfa23f
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE4ReportBuilderRunner.java
@@ -0,0 +1,715 @@
+/*
+ * 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.asterix.experiment.report;
+
+import java.io.BufferedReader;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class SIE4ReportBuilderRunner {
+    static boolean IS_PROFILE = false;
+    String outputFilePath = "/Users/kisskys/workspace/asterix_master/resultLog/MemBuf3g-DiskBuf3g-Lsev-Jvm7g-Lock0g/result-report/";
+    SIE3ReportBuilder sie4Dhbtree;
+    SIE3ReportBuilder sie4Dhvbtree;
+    SIE3ReportBuilder sie4Rtree;
+    SIE3ReportBuilder sie4Shbtree;
+    SIE3ReportBuilder sie4Sif;
+
+    //for profiling report -------------------------------------
+    String profileFileHomeDir;
+    String indexSearchTimeFilePath;
+    String falsePositiveFilePath;
+    String cacheMissFilePath;
+    ProfilerReportBuilder dhbtreeProfiler;
+    ProfilerReportBuilder dhvbtreeProfiler;
+    ProfilerReportBuilder rtreeProfiler;
+    ProfilerReportBuilder shbtreeProfiler;
+    ProfilerReportBuilder sifProfiler;
+    //for profiling report -------------------------------------
+
+    StringBuilder sb = new StringBuilder();
+
+    public SIE4ReportBuilderRunner() {
+        String expHomePath = "/Users/kisskys/workspace/asterix_master/resultLog/MemBuf3g-DiskBuf3g-Lsev-Jvm7g-Lock0g/exp4/";
+        String runLogFileName = "run-exp4.log";
+        String queryLogFileNamePrefix = "QueryGenResult-";
+        String queryLogFileNameSuffix = "-130.149.249.51.txt";
+
+        sie4Dhbtree = new SIE3ReportBuilder(expHomePath, "SpatialIndexExperiment4Dhbtree", runLogFileName,
+                queryLogFileNamePrefix + "SpatialIndexExperiment4Dhbtree" + queryLogFileNameSuffix);
+        sie4Dhvbtree = new SIE3ReportBuilder(expHomePath, "SpatialIndexExperiment4Dhvbtree", runLogFileName,
+                queryLogFileNamePrefix + "SpatialIndexExperiment4Dhvbtree" + queryLogFileNameSuffix);
+        sie4Rtree = new SIE3ReportBuilder(expHomePath, "SpatialIndexExperiment4Rtree", runLogFileName,
+                queryLogFileNamePrefix + "SpatialIndexExperiment4Rtree" + queryLogFileNameSuffix);
+        sie4Shbtree = new SIE3ReportBuilder(expHomePath, "SpatialIndexExperiment4Shbtree", runLogFileName,
+                queryLogFileNamePrefix + "SpatialIndexExperiment4Shbtree" + queryLogFileNameSuffix);
+        sie4Sif = new SIE3ReportBuilder(expHomePath, "SpatialIndexExperiment4Sif", runLogFileName,
+                queryLogFileNamePrefix + "SpatialIndexExperiment4Sif" + queryLogFileNameSuffix);
+    }
+
+    public void generateIndexCreationTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 index creation time report\n");
+        sb.append("index type, index creation time\n");
+        sb.append("dhbtree,").append(sie4Dhbtree.getIndexCreationTime()).append("\n");
+        sb.append("dhvbtree,").append(sie4Dhvbtree.getIndexCreationTime()).append("\n");
+        sb.append("rtree,").append(sie4Rtree.getIndexCreationTime()).append("\n");
+        sb.append("shbtree,").append(sie4Shbtree.getIndexCreationTime()).append("\n");
+        sb.append("sif,").append(sie4Sif.getIndexCreationTime()).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie4_index_creation_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateIndexSize() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 index size report\n");
+
+        sb.append("index type, index size\n");
+        sb.append("dhbtree,").append(sie4Dhbtree.getIndexSize("Tweets_idx_dhbtreeLocation/device_id")).append("\n");
+        sb.append("dhvbtree,").append(sie4Dhvbtree.getIndexSize("Tweets_idx_dhvbtreeLocation/device_id")).append("\n");
+        sb.append("rtree,").append(sie4Rtree.getIndexSize("Tweets_idx_rtreeLocation/device_id")).append("\n");
+        sb.append("shbtree,").append(sie4Shbtree.getIndexSize("Tweets_idx_shbtreeLocation/device_id")).append("\n");
+        sb.append("sif,").append(sie4Sif.getIndexSize("Tweets_idx_sifLocation/device_id")).append("\n");
+        sb.append("# pidx,").append(sie4Sif.getIndexSize("Tweets_idx_Tweets/device_id")).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie4_sidx_size.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryResponseTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 select query response time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie4Dhbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie4Dhvbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie4Rtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie4Shbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie4Sif.getSelectQueryResponseTime(0)).append("\n");
+        sb.append("0.0001,").append(sie4Dhbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie4Dhvbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie4Rtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie4Shbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie4Sif.getSelectQueryResponseTime(1)).append("\n");
+        sb.append("0.001,").append(sie4Dhbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie4Dhvbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie4Rtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie4Shbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie4Sif.getSelectQueryResponseTime(2)).append("\n");
+        sb.append("0.01,").append(sie4Dhbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie4Dhvbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie4Rtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie4Shbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie4Sif.getSelectQueryResponseTime(3)).append("\n");
+        sb.append("0.1,").append(sie4Dhbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie4Dhvbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie4Rtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie4Shbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie4Sif.getSelectQueryResponseTime(4)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie4_select_query_response_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryResultCount() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 select query result count report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie4Dhbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie4Dhvbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie4Rtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie4Shbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie4Sif.getSelectQueryResultCount(0)).append("\n");
+        sb.append("0.0001,").append(sie4Dhbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie4Dhvbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie4Rtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie4Shbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie4Sif.getSelectQueryResultCount(1)).append("\n");
+        sb.append("0.001,").append(sie4Dhbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie4Dhvbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie4Rtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie4Shbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie4Sif.getSelectQueryResultCount(2)).append("\n");
+        sb.append("0.01,").append(sie4Dhbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie4Dhvbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie4Rtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie4Shbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie4Sif.getSelectQueryResultCount(3)).append("\n");
+        sb.append("0.1,").append(sie4Dhbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie4Dhvbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie4Rtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie4Shbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie4Sif.getSelectQueryResultCount(4)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper
+                .openOutputFile(outputFilePath + "sie4_select_query_result_count.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryResponseTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 join query response time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie4Dhbtree.getJoinQueryResponseTime(0)).append(",")
+                .append(sie4Dhvbtree.getJoinQueryResponseTime(0)).append(",")
+                .append(sie4Rtree.getJoinQueryResponseTime(0)).append(",")
+                .append(sie4Shbtree.getJoinQueryResponseTime(0)).append(",")
+                .append(sie4Sif.getJoinQueryResponseTime(0)).append("\n");
+        sb.append("0.0001,").append(sie4Dhbtree.getJoinQueryResponseTime(1)).append(",")
+                .append(sie4Dhvbtree.getJoinQueryResponseTime(1)).append(",")
+                .append(sie4Rtree.getJoinQueryResponseTime(1)).append(",")
+                .append(sie4Shbtree.getJoinQueryResponseTime(1)).append(",")
+                .append(sie4Sif.getJoinQueryResponseTime(1)).append("\n");
+        sb.append("0.001,").append(sie4Dhbtree.getJoinQueryResponseTime(2)).append(",")
+                .append(sie4Dhvbtree.getJoinQueryResponseTime(2)).append(",")
+                .append(sie4Rtree.getJoinQueryResponseTime(2)).append(",")
+                .append(sie4Shbtree.getJoinQueryResponseTime(2)).append(",")
+                .append(sie4Sif.getJoinQueryResponseTime(2)).append("\n");
+        sb.append("0.01,").append(sie4Dhbtree.getJoinQueryResponseTime(3)).append(",")
+                .append(sie4Dhvbtree.getJoinQueryResponseTime(3)).append(",")
+                .append(sie4Rtree.getJoinQueryResponseTime(3)).append(",")
+                .append(sie4Shbtree.getJoinQueryResponseTime(3)).append(",")
+                .append(sie4Sif.getJoinQueryResponseTime(3)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie4_join_query_response_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryResultCount() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 join query result count report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie4Dhbtree.getJoinQueryResultCount(0)).append(",")
+                .append(sie4Dhvbtree.getJoinQueryResultCount(0)).append(",")
+                .append(sie4Rtree.getJoinQueryResultCount(0)).append(",")
+                .append(sie4Shbtree.getJoinQueryResultCount(0)).append(",").append(sie4Sif.getJoinQueryResultCount(0))
+                .append("\n");
+        sb.append("0.0001,").append(sie4Dhbtree.getJoinQueryResultCount(1)).append(",")
+                .append(sie4Dhvbtree.getJoinQueryResultCount(1)).append(",")
+                .append(sie4Rtree.getJoinQueryResultCount(1)).append(",")
+                .append(sie4Shbtree.getJoinQueryResultCount(1)).append(",").append(sie4Sif.getJoinQueryResultCount(1))
+                .append("\n");
+        sb.append("0.001,").append(sie4Dhbtree.getJoinQueryResultCount(2)).append(",")
+                .append(sie4Dhvbtree.getJoinQueryResultCount(2)).append(",")
+                .append(sie4Rtree.getJoinQueryResultCount(2)).append(",")
+                .append(sie4Shbtree.getJoinQueryResultCount(2)).append(",").append(sie4Sif.getJoinQueryResultCount(2))
+                .append("\n");
+        sb.append("0.01,").append(sie4Dhbtree.getJoinQueryResultCount(3)).append(",")
+                .append(sie4Dhvbtree.getJoinQueryResultCount(3)).append(",")
+                .append(sie4Rtree.getJoinQueryResultCount(3)).append(",")
+                .append(sie4Shbtree.getJoinQueryResultCount(3)).append(",").append(sie4Sif.getJoinQueryResultCount(3))
+                .append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie4_join_query_result_count.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryProfiledSidxSearchTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 select query profiled sidx search time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(true, false, 0, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 0, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 0, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 0, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 0, 0)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(true, false, 1, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 1, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 1, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 1, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 1, 0)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(true, false, 2, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 2, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 2, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 2, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 2, 0)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(true, false, 3, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 3, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 3, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 3, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 3, 0)).append("\n");
+        sb.append("0.1,").append(dhbtreeProfiler.getIdxNumber(true, false, 4, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 4, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 4, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 4, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 4, 0)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie4_select_query_profiled_sidx_search_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryProfiledPidxSearchTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 select query profiled pidx search time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(true, false, 0, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 0, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 0, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 0, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 0, 1)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(true, false, 1, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 1, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 1, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 1, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 1, 1)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(true, false, 2, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 2, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 2, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 2, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 2, 1)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(true, false, 3, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 3, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 3, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 3, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 3, 1)).append("\n");
+        sb.append("0.1,").append(dhbtreeProfiler.getIdxNumber(true, false, 4, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, false, 4, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, false, 4, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, false, 4, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, false, 4, 1)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie4_select_query_profiled_pidx_search_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledSidxSearchTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 join query profiled sidx search time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(true, true, 0, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 0, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 0, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 0, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 0, 1)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(true, true, 1, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 1, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 1, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 1, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 1, 1)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(true, true, 2, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 2, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 2, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 2, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 2, 1)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(true, true, 3, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 3, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 3, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 3, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 3, 1)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie4_join_query_profiled_sidx_search_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledPidxSearchTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 join query profiled pidx search time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(true, true, 0, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 0, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 0, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 0, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 0, 2)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(true, true, 1, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 1, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 1, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 1, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 1, 2)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(true, true, 2, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 2, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 2, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 2, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 2, 2)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(true, true, 3, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 3, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 3, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 3, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 3, 2)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie4_join_query_profiled_pidx_search_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledSeedPidxSearchTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 join query profiled query seed pidx search time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(true, true, 0, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 0, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 0, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 0, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 0, 0)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(true, true, 1, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 1, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 1, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 1, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 1, 0)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(true, true, 2, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 2, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 2, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 2, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 2, 0)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(true, true, 3, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(true, true, 3, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(true, true, 3, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(true, true, 3, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(true, true, 3, 0)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie4_join_query_profiled_seed_pidx_search_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryProfiledSidxCacheMiss() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 select query profiled sidx cache miss report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(false, false, 0, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 0, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 0, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 0, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 0, 0)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(false, false, 1, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 1, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 1, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 1, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 1, 0)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(false, false, 2, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 2, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 2, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 2, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 2, 0)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(false, false, 3, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 3, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 3, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 3, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 3, 0)).append("\n");
+        sb.append("0.1,").append(dhbtreeProfiler.getIdxNumber(false, false, 4, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 4, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 4, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 4, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 4, 0)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie4_select_query_profiled_sidx_cache_miss.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryProfiledPidxCacheMiss() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 select query profiled pidx cache miss report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(false, false, 0, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 0, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 0, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 0, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 0, 1)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(false, false, 1, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 1, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 1, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 1, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 1, 1)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(false, false, 2, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 2, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 2, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 2, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 2, 1)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(false, false, 3, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 3, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 3, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 3, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 3, 1)).append("\n");
+        sb.append("0.1,").append(dhbtreeProfiler.getIdxNumber(false, false, 4, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, false, 4, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, false, 4, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, false, 4, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, false, 4, 1)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie4_select_query_profiled_pidx_cache_miss.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledSidxCacheMiss() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 join query profiled sidx cache miss report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(false, true, 0, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 0, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 0, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 0, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 0, 1)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(false, true, 1, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 1, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 1, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 1, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 1, 1)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(false, true, 2, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 2, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 2, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 2, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 2, 1)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(false, true, 3, 1)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 3, 1)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 3, 1)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 3, 1)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 3, 1)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie4_join_query_profiled_sidx_cache_miss.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledPidxCacheMiss() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 join query profiled pidx cache miss report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(false, true, 0, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 0, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 0, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 0, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 0, 2)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(false, true, 1, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 1, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 1, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 1, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 1, 2)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(false, true, 2, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 2, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 2, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 2, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 2, 2)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(false, true, 3, 2)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 3, 2)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 3, 2)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 3, 2)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 3, 2)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie4_join_query_profiled_pidx_cache_miss.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledSeedPidxCacheMiss() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 join query profiled query seed pidx search time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getIdxNumber(false, true, 0, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 0, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 0, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 0, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 0, 0)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getIdxNumber(false, true, 1, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 1, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 1, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 1, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 1, 0)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getIdxNumber(false, true, 2, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 2, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 2, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 2, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 2, 0)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getIdxNumber(false, true, 3, 0)).append(",")
+                .append(dhvbtreeProfiler.getIdxNumber(false, true, 3, 0)).append(",")
+                .append(rtreeProfiler.getIdxNumber(false, true, 3, 0)).append(",")
+                .append(shbtreeProfiler.getIdxNumber(false, true, 3, 0)).append(",")
+                .append(sifProfiler.getIdxNumber(false, true, 3, 0)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie4_join_query_profiled_seed_pidx_cache_miss.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryProfiledFalsePositive() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 select query profiled false positive raw report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getFalsePositives(false, 0)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(false, 0)).append(",")
+                .append(rtreeProfiler.getFalsePositives(false, 0)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(false, 0)).append(",")
+                .append(sifProfiler.getFalsePositives(false, 0)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getFalsePositives(false, 1)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(false, 1)).append(",")
+                .append(rtreeProfiler.getFalsePositives(false, 1)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(false, 1)).append(",")
+                .append(sifProfiler.getFalsePositives(false, 1)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getFalsePositives(false, 2)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(false, 2)).append(",")
+                .append(rtreeProfiler.getFalsePositives(false, 2)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(false, 2)).append(",")
+                .append(sifProfiler.getFalsePositives(false, 2)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getFalsePositives(false, 3)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(false, 3)).append(",")
+                .append(rtreeProfiler.getFalsePositives(false, 3)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(false, 3)).append(",")
+                .append(sifProfiler.getFalsePositives(false, 3)).append("\n");
+        sb.append("0.1,").append(dhbtreeProfiler.getFalsePositives(false, 4)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(false, 4)).append(",")
+                .append(rtreeProfiler.getFalsePositives(false, 4)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(false, 4)).append(",")
+                .append(sifProfiler.getFalsePositives(false, 4)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie4_select_query_profiled_false_positive_raw.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+        generateFalsePositive(outputFilePath + "sie4_select_query_profiled_false_positive_raw.txt", outputFilePath
+                + "sie4_select_query_result_count.txt", outputFilePath
+                + "sie4_select_query_profiled_false_positive.txt", false);
+    }
+
+    private void generateFalsePositive(String falsePositveFile, String queryResultCountFile, String outputFile,
+            boolean isJoin) throws IOException {
+
+        String[] fps, rcs;
+        sb.setLength(0);
+
+        BufferedReader brFalsePositive = new BufferedReader(new FileReader(falsePositveFile));
+        BufferedReader brQueryResultCount = new BufferedReader(new FileReader(queryResultCountFile));
+
+        //discard two head lines
+        brFalsePositive.readLine();
+        brFalsePositive.readLine();
+        brQueryResultCount.readLine();
+        brQueryResultCount.readLine();
+
+        int radiusCount = isJoin ? 4 : 5;
+        int partitionCount = 24;
+        String[] radius = { "0.00001", "0.0001", "0.001", "0.01", "0.1" };
+
+        if (isJoin) {
+            sb.append("# sie4 join query profiled false positive report\n");
+        } else {
+            sb.append("# sie4 select query profiled false positive report\n");
+        }
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+
+        for (int i = 0; i < radiusCount; i++) {
+            fps = brFalsePositive.readLine().split(",");
+            rcs = brQueryResultCount.readLine().split(",");
+            //false positive count
+            sb.append(radius[i])
+                    .append(",")
+                    .append(((Double.parseDouble(fps[1]) * partitionCount) - Double.parseDouble(rcs[1]))
+                            / partitionCount)
+                    .append(",")
+                    .append(((Double.parseDouble(fps[2]) * partitionCount) - Double.parseDouble(rcs[2]))
+                            / partitionCount)
+                    .append(",")
+                    .append(((Double.parseDouble(fps[3]) * partitionCount) - Double.parseDouble(rcs[3]))
+                            / partitionCount)
+                    .append(",")
+                    .append(((Double.parseDouble(fps[4]) * partitionCount) - Double.parseDouble(rcs[4]))
+                            / partitionCount)
+                    .append(",")
+                    .append(((Double.parseDouble(fps[5]) * partitionCount) - Double.parseDouble(rcs[5]))
+                            / partitionCount).append("\n");
+            //false positive rate
+            //            sb.append(radius[i])
+            //            .append(",").append(((Double.parseDouble(fps[1]) * partitionCount) - Double.parseDouble(rcs[1]))/(Double.parseDouble(fps[1]) * partitionCount))
+            //            .append(",").append(((Double.parseDouble(fps[2]) * partitionCount) - Double.parseDouble(rcs[2]))/(Double.parseDouble(fps[2]) * partitionCount))
+            //            .append(",").append(((Double.parseDouble(fps[3]) * partitionCount) - Double.parseDouble(rcs[3]))/(Double.parseDouble(fps[3]) * partitionCount))
+            //            .append(",").append(((Double.parseDouble(fps[4]) * partitionCount) - Double.parseDouble(rcs[4]))/(Double.parseDouble(fps[4]) * partitionCount))
+            //            .append(",").append(((Double.parseDouble(fps[5]) * partitionCount) - Double.parseDouble(rcs[5]))/(Double.parseDouble(fps[5]) * partitionCount))
+            //            .append("\n");
+        }
+        brFalsePositive.close();
+        brQueryResultCount.close();
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFile);
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateJoinQueryProfiledFalsePositive() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie4 join query profiled false positive raw report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(dhbtreeProfiler.getFalsePositives(true, 0)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(true, 0)).append(",")
+                .append(rtreeProfiler.getFalsePositives(true, 0)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(true, 0)).append(",")
+                .append(sifProfiler.getFalsePositives(true, 0)).append("\n");
+        sb.append("0.0001,").append(dhbtreeProfiler.getFalsePositives(true, 1)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(true, 1)).append(",")
+                .append(rtreeProfiler.getFalsePositives(true, 1)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(true, 1)).append(",")
+                .append(sifProfiler.getFalsePositives(true, 1)).append("\n");
+        sb.append("0.001,").append(dhbtreeProfiler.getFalsePositives(true, 2)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(true, 2)).append(",")
+                .append(rtreeProfiler.getFalsePositives(true, 2)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(true, 2)).append(",")
+                .append(sifProfiler.getFalsePositives(true, 2)).append("\n");
+        sb.append("0.01,").append(dhbtreeProfiler.getFalsePositives(true, 3)).append(",")
+                .append(dhvbtreeProfiler.getFalsePositives(true, 3)).append(",")
+                .append(rtreeProfiler.getFalsePositives(true, 3)).append(",")
+                .append(shbtreeProfiler.getFalsePositives(true, 3)).append(",")
+                .append(sifProfiler.getFalsePositives(true, 3)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie4_join_query_profiled_false_positive_raw.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        generateFalsePositive(outputFilePath + "sie4_join_query_profiled_false_positive_raw.txt", outputFilePath
+                + "sie4_join_query_result_count.txt", outputFilePath + "sie4_join_query_profiled_false_positive.txt",
+                true);
+    }
+
+}
diff --git a/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE5ReportBuilderRunner.java b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE5ReportBuilderRunner.java
new file mode 100644
index 0000000..2cd8588
--- /dev/null
+++ b/asterix-experiments/src/main/java/org/apache/asterix/experiment/report/SIE5ReportBuilderRunner.java
@@ -0,0 +1,459 @@
+/*
+ * 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.asterix.experiment.report;
+
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+
+public class SIE5ReportBuilderRunner {
+    String expHomePath = "/Users/kisskys/workspace/asterix_master/resultLog/MemBuf3g-DiskBuf3g-Lsev-Jvm7g-Lock0g/exp5-4/";
+    String runLogFileName = "run-exp5-4.log";
+    String outputFilePath = "/Users/kisskys/workspace/asterix_master/resultLog/MemBuf3g-DiskBuf3g-Lsev-Jvm7g-Lock0g/result-report/";
+
+    SIE2ReportBuilder sie5Dhbtree = new SIE2ReportBuilder(expHomePath, "SpatialIndexExperiment5Dhbtree", runLogFileName);
+    SIE2ReportBuilder sie5Dhvbtree = new SIE2ReportBuilder(expHomePath, "SpatialIndexExperiment5Dhvbtree",
+            runLogFileName);
+    SIE2ReportBuilder sie5Rtree = new SIE2ReportBuilder(expHomePath, "SpatialIndexExperiment5Rtree", runLogFileName);
+    SIE2ReportBuilder sie5Shbtree = new SIE2ReportBuilder(expHomePath, "SpatialIndexExperiment5Shbtree", runLogFileName);
+    SIE2ReportBuilder sie5Sif = new SIE2ReportBuilder(expHomePath, "SpatialIndexExperiment5Sif", runLogFileName);
+
+    StringBuilder sb = new StringBuilder();
+
+    /**
+     * generate sie5_overall_insert_ps.txt
+     */
+    public void generateOverallInsertPS() throws Exception {
+        int targetRound = 721; //(3600 seconds / 5seconds) + 1
+
+        ArrayList<Long> ipsListDhbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListDhvbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListRtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListShbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListSif = new ArrayList<Long>();
+        sie5Dhbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListDhbtree);
+        sie5Dhvbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListDhvbtree);
+        sie5Rtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListRtree);
+        sie5Shbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListShbtree);
+        sie5Sif.getAllNodesAccumulatedInsertPS(targetRound, ipsListSif);
+
+        sb.setLength(0);
+        sb.append("# sie5 60min inserts per second report\n");
+        sb.append("index type, InsertPS\n");
+        sb.append("dhbtree,").append(ipsListDhbtree.get(targetRound - 1)).append("\n");
+        sb.append("dhvbtree,").append(ipsListDhvbtree.get(targetRound - 1)).append("\n");
+        sb.append("rtree,").append(ipsListRtree.get(targetRound - 1)).append("\n");
+        sb.append("shbtree,").append(ipsListShbtree.get(targetRound - 1)).append("\n");
+        sb.append("sif,").append(ipsListSif.get(targetRound - 1)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie5_overall_insert_ps.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        ipsListDhbtree.clear();
+        ipsListDhvbtree.clear();
+        ipsListRtree.clear();
+        ipsListShbtree.clear();
+        ipsListSif.clear();
+    }
+
+    /**
+     * generate sie5_accumulated_insert_ps.txt
+     */
+    public void generateAccumulatedInsertPS() throws Exception {
+        int targetRound = 721; //(3600 seconds / 5seconds) + 1
+        int roundInterval = 5;
+
+        ArrayList<Long> ipsListDhbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListDhvbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListRtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListShbtree = new ArrayList<Long>();
+        ArrayList<Long> ipsListSif = new ArrayList<Long>();
+        sie5Dhbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListDhbtree);
+        sie5Dhvbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListDhvbtree);
+        sie5Rtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListRtree);
+        sie5Shbtree.getAllNodesAccumulatedInsertPS(targetRound, ipsListShbtree);
+        sie5Sif.getAllNodesAccumulatedInsertPS(targetRound, ipsListSif);
+
+        sb.setLength(0);
+        sb.append("# sie5 accumulated inserts per second report\n");
+        sb.append("# time, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+
+        for (int i = 0; i < targetRound; i++) {
+            sb.append("" + (i * roundInterval) + "," + ipsListDhbtree.get(i) + "," + ipsListDhvbtree.get(i) + ","
+                    + ipsListRtree.get(i) + "," + ipsListShbtree.get(i) + "," + ipsListSif.get(i) + "\n");
+        }
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie5_accumulated_insert_ps.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        ipsListDhbtree.clear();
+        ipsListDhvbtree.clear();
+        ipsListRtree.clear();
+        ipsListShbtree.clear();
+        ipsListSif.clear();
+    }
+
+    public void generateQueryPS() throws Exception {
+        int minutes = 60;
+        sb.setLength(0);
+        sb.append("# sie5 queries per second report\n");
+        sb.append("index type, QueryPS\n");
+        sb.append("dhbtree,").append(sie5Dhbtree.getQueryPS(minutes)).append("\n");
+        sb.append("dhvbtree,").append(sie5Dhvbtree.getQueryPS(minutes)).append("\n");
+        sb.append("rtree,").append(sie5Rtree.getQueryPS(minutes)).append("\n");
+        sb.append("shbtree,").append(sie5Shbtree.getQueryPS(minutes)).append("\n");
+        sb.append("sif,").append(sie5Sif.getQueryPS(minutes)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie5_query_ps.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateAverageQueryResultCount() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie5 average query result count report\n");
+        sb.append("index type, query result count\n");
+        sb.append("dhbtree,").append(sie5Dhbtree.getAverageQueryResultCount()).append("\n");
+        sb.append("dhvbtree,").append(sie5Dhvbtree.getAverageQueryResultCount()).append("\n");
+        sb.append("rtree,").append(sie5Rtree.getAverageQueryResultCount()).append("\n");
+        sb.append("shbtree,").append(sie5Shbtree.getAverageQueryResultCount()).append("\n");
+        sb.append("sif,").append(sie5Sif.getAverageQueryResultCount()).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie5_average_query_result_count.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateAverageQueryResponseTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie5 average query response time report\n");
+        sb.append("index type, query response time\n");
+        sb.append("dhbtree,").append(sie5Dhbtree.getAverageQueryResponseTime()).append("\n");
+        sb.append("dhvbtree,").append(sie5Dhvbtree.getAverageQueryResponseTime()).append("\n");
+        sb.append("rtree,").append(sie5Rtree.getAverageQueryResponseTime()).append("\n");
+        sb.append("shbtree,").append(sie5Shbtree.getAverageQueryResponseTime()).append("\n");
+        sb.append("sif,").append(sie5Sif.getAverageQueryResponseTime()).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie5_average_query_response_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateInstantaneousInsertPS() throws Exception {
+        for (int i = 0; i < 8; i++) {
+            sb.setLength(0);
+            sb.append("# sie5 instantaneous inserts per second report\n");
+            sb.append(sie5Dhbtree.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie5_instantaneous_insert_ps_dhbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 8; i++) {
+            sb.setLength(0);
+            sb.append("# sie5 instantaneous inserts per second report\n");
+            sb.append(sie5Dhvbtree.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie5_instantaneous_insert_ps_dhvbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 8; i++) {
+            sb.setLength(0);
+            sb.append("# sie5 instantaneous inserts per second report\n");
+            sb.append(sie5Rtree.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie5_instantaneous_insert_ps_rtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 8; i++) {
+            sb.setLength(0);
+            sb.append("# sie5 instantaneous inserts per second report\n");
+            sb.append(sie5Shbtree.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie5_instantaneous_insert_ps_shbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 8; i++) {
+            sb.setLength(0);
+            sb.append("# sie5 instantaneous inserts per second report\n");
+            sb.append(sie5Sif.getInstantaneousInsertPS(i, false));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie5_instantaneous_insert_ps_sif_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+    }
+
+    public void generateGanttInstantaneousInsertPS() throws Exception {
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie5 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie5Dhbtree.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie5_gantt_1node_instantaneous_insert_ps_dhbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie5 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie5Dhvbtree.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie5_gantt_1node_instantaneous_insert_ps_dhvbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie5 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie5Rtree.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie5_gantt_1node_instantaneous_insert_ps_rtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie5 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie5Shbtree.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie5_gantt_1node_instantaneous_insert_ps_shbtree_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+        for (int i = 0; i < 1; i++) {
+            sb.setLength(0);
+            sb.append("# sie5 8nodes(8 dataGen) instantaneous inserts per second report\n");
+            sb.append(sie5Sif.getInstantaneousInsertPS(i, true));
+            FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                    + "sie5_gantt_1node_instantaneous_insert_ps_sif_gen" + i + ".txt");
+            fos.write(sb.toString().getBytes());
+            ReportBuilderHelper.closeOutputFile(fos);
+        }
+
+        long dataGenStartTime = sie5Dhbtree.getDataGenStartTimeStamp();
+        NCLogReportBuilder ncLogReportBuilder = new NCLogReportBuilder(expHomePath
+                + "SpatialIndexExperiment5Dhbtree/logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie5_gantt_1node_flush_merge_dhbtree.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        dataGenStartTime = sie5Dhvbtree.getDataGenStartTimeStamp();
+        ncLogReportBuilder = new NCLogReportBuilder(expHomePath + "SpatialIndexExperiment5Dhvbtree/logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie5_gantt_1node_flush_merge_dhvbtree.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        dataGenStartTime = sie5Rtree.getDataGenStartTimeStamp();
+        ncLogReportBuilder = new NCLogReportBuilder(expHomePath + "SpatialIndexExperiment5Rtree/logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie5_gantt_1node_flush_merge_rtree.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        dataGenStartTime = sie5Shbtree.getDataGenStartTimeStamp();
+        ncLogReportBuilder = new NCLogReportBuilder(expHomePath + "SpatialIndexExperiment5Shbtree/logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie5_gantt_1node_flush_merge_shbtree.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        dataGenStartTime = sie5Sif.getDataGenStartTimeStamp();
+        ncLogReportBuilder = new NCLogReportBuilder(expHomePath + "SpatialIndexExperiment5Sif/logs/a1_node1.log");
+        sb.setLength(0);
+        sb.append(ncLogReportBuilder.getFlushMergeEventAsGanttChartFormat(dataGenStartTime));
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie5_gantt_1node_flush_merge_sif.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryResponseTime() throws Exception {
+        sb.setLength(0);
+        sb.append("# sie5 select query response time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie5Dhbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie5Rtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie5Shbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie5Sif.getSelectQueryResponseTime(0)).append("\n");
+        sb.append("0.0001,").append(sie5Dhbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie5Rtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie5Shbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie5Sif.getSelectQueryResponseTime(1)).append("\n");
+        sb.append("0.001,").append(sie5Dhbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie5Rtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie5Shbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie5Sif.getSelectQueryResponseTime(2)).append("\n");
+        sb.append("0.01,").append(sie5Dhbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie5Rtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie5Shbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie5Sif.getSelectQueryResponseTime(3)).append("\n");
+        sb.append("0.1,").append(sie5Dhbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie5Rtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie5Shbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie5Sif.getSelectQueryResponseTime(4)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper.openOutputFile(outputFilePath
+                + "sie5_select_query_response_time.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        sb.setLength(0);
+        sb.append("# sie5 select query response time report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie5Dhbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie5Rtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie5Shbtree.getSelectQueryResponseTime(0)).append(",")
+                .append(sie5Sif.getSelectQueryResponseTime(0)).append("\n");
+        sb.append("0.0001,").append(sie5Dhbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie5Rtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie5Shbtree.getSelectQueryResponseTime(1)).append(",")
+                .append(sie5Sif.getSelectQueryResponseTime(1)).append("\n");
+        sb.append("0.001,").append(sie5Dhbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie5Rtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie5Shbtree.getSelectQueryResponseTime(2)).append(",")
+                .append(sie5Sif.getSelectQueryResponseTime(2)).append("\n");
+
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie5_select_query_response_time1.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        sb.setLength(0);
+        sb.append("# sie5 select query response time 2 report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.01,").append(sie5Dhbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie5Rtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie5Shbtree.getSelectQueryResponseTime(3)).append(",")
+                .append(sie5Sif.getSelectQueryResponseTime(3)).append("\n");
+        sb.append("0.1,").append(sie5Dhbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie5Rtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie5Shbtree.getSelectQueryResponseTime(4)).append(",")
+                .append(sie5Sif.getSelectQueryResponseTime(4)).append("\n");
+
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie5_select_query_response_time2.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+
+    public void generateSelectQueryResultCount() throws Exception {
+
+        sb.setLength(0);
+        sb.append("# sie5 select query result count report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie5Dhbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie5Rtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie5Shbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie5Sif.getSelectQueryResultCount(0)).append("\n");
+        sb.append("0.0001,").append(sie5Dhbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie5Rtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie5Shbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie5Sif.getSelectQueryResultCount(1)).append("\n");
+        sb.append("0.001,").append(sie5Dhbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie5Rtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie5Shbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie5Sif.getSelectQueryResultCount(2)).append("\n");
+        sb.append("0.01,").append(sie5Dhbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie5Rtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie5Shbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie5Sif.getSelectQueryResultCount(3)).append("\n");
+        sb.append("0.1,").append(sie5Dhbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie5Rtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie5Shbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie5Sif.getSelectQueryResultCount(4)).append("\n");
+
+        FileOutputStream fos = ReportBuilderHelper
+                .openOutputFile(outputFilePath + "sie5_select_query_result_count.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        sb.setLength(0);
+        sb.append("# sie5 select query result count 1 report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.00001,").append(sie5Dhbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie5Rtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie5Shbtree.getSelectQueryResultCount(0)).append(",")
+                .append(sie5Sif.getSelectQueryResultCount(0)).append("\n");
+        sb.append("0.0001,").append(sie5Dhbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie5Rtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie5Shbtree.getSelectQueryResultCount(1)).append(",")
+                .append(sie5Sif.getSelectQueryResultCount(1)).append("\n");
+        sb.append("0.001,").append(sie5Dhbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie5Rtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie5Shbtree.getSelectQueryResultCount(2)).append(",")
+                .append(sie5Sif.getSelectQueryResultCount(2)).append("\n");
+
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie5_select_query_result_count1.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+
+        sb.setLength(0);
+        sb.append("# sie5 select query result count 2 report\n");
+
+        sb.append("radius, dhbtree, dhvbtree, rtree, shbtree, sif\n");
+        sb.append("0.01,").append(sie5Dhbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie5Rtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie5Shbtree.getSelectQueryResultCount(3)).append(",")
+                .append(sie5Sif.getSelectQueryResultCount(3)).append("\n");
+        sb.append("0.1,").append(sie5Dhbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie5Dhvbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie5Rtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie5Shbtree.getSelectQueryResultCount(4)).append(",")
+                .append(sie5Sif.getSelectQueryResultCount(4)).append("\n");
+
+        fos = ReportBuilderHelper.openOutputFile(outputFilePath + "sie5_select_query_result_count2.txt");
+        fos.write(sb.toString().getBytes());
+        ReportBuilderHelper.closeOutputFile(fos);
+    }
+}
diff --git a/asterix-experiments/src/main/resources/gantt/foo.eps b/asterix-experiments/src/main/resources/gantt/foo.eps
new file mode 100644
index 0000000..0f13788
--- /dev/null
+++ b/asterix-experiments/src/main/resources/gantt/foo.eps
@@ -0,0 +1,928 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: foo.eps
+%%Creator: gnuplot 4.6 patchlevel 5
+%%CreationDate: Sat Jul 11 23:19:23 2015
+%%DocumentFonts: (atend)
+%%BoundingBox: 50 50 410 302
+%%EndComments
+%%BeginProlog
+/gnudict 256 dict def
+gnudict begin
+%
+% The following true/false flags may be edited by hand if desired.
+% The unit line width and grayscale image gamma correction may also be changed.
+%
+/Color true def
+/Blacktext false def
+/Solid true def
+/Dashlength 1 def
+/Landscape false def
+/Level1 false def
+/Rounded false def
+/ClipToBoundingBox false def
+/SuppressPDFMark false def
+/TransparentPatterns false def
+/gnulinewidth 5.000 def
+/userlinewidth gnulinewidth def
+/Gamma 1.0 def
+/BackgroundColor {-1.000 -1.000 -1.000} def
+%
+/vshift -46 def
+/dl1 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul sub dup 0 le { pop 0.01 } if } if
+} def
+/dl2 {
+  10.0 Dashlength mul mul
+  Rounded { currentlinewidth 0.75 mul add } if
+} def
+/hpt_ 31.5 def
+/vpt_ 31.5 def
+/hpt hpt_ def
+/vpt vpt_ def
+/doclip {
+  ClipToBoundingBox {
+    newpath 50 50 moveto 410 50 lineto 410 302 lineto 50 302 lineto closepath
+    clip
+  } if
+} def
+%
+% Gnuplot Prolog Version 4.6 (September 2012)
+%
+%/SuppressPDFMark true def
+%
+/M {moveto} bind def
+/L {lineto} bind def
+/R {rmoveto} bind def
+/V {rlineto} bind def
+/N {newpath moveto} bind def
+/Z {closepath} bind def
+/C {setrgbcolor} bind def
+/f {rlineto fill} bind def
+/g {setgray} bind def
+/Gshow {show} def   % May be redefined later in the file to support UTF-8
+/vpt2 vpt 2 mul def
+/hpt2 hpt 2 mul def
+/Lshow {currentpoint stroke M 0 vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Rshow {currentpoint stroke M dup stringwidth pop neg vshift R
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/Cshow {currentpoint stroke M dup stringwidth pop -2 div vshift R 
+	Blacktext {gsave 0 setgray show grestore} {show} ifelse} def
+/UP {dup vpt_ mul /vpt exch def hpt_ mul /hpt exch def
+  /hpt2 hpt 2 mul def /vpt2 vpt 2 mul def} def
+/DL {Color {setrgbcolor Solid {pop []} if 0 setdash}
+ {pop pop pop 0 setgray Solid {pop []} if 0 setdash} ifelse} def
+/BL {stroke userlinewidth 2 mul setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/AL {stroke userlinewidth 2 div setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+/UL {dup gnulinewidth mul /userlinewidth exch def
+	dup 1 lt {pop 1} if 10 mul /udl exch def} def
+/PL {stroke userlinewidth setlinewidth
+	Rounded {1 setlinejoin 1 setlinecap} if} def
+3.8 setmiterlimit
+% Default Line colors
+/LCw {1 1 1} def
+/LCb {0 0 0} def
+/LCa {0 0 0} def
+/LC0 {1 0 0} def
+/LC1 {0 1 0} def
+/LC2 {0 0 1} def
+/LC3 {1 0 1} def
+/LC4 {0 1 1} def
+/LC5 {1 1 0} def
+/LC6 {0 0 0} def
+/LC7 {1 0.3 0} def
+/LC8 {0.5 0.5 0.5} def
+% Default Line Types
+/LTw {PL [] 1 setgray} def
+/LTb {BL [] LCb DL} def
+/LTa {AL [1 udl mul 2 udl mul] 0 setdash LCa setrgbcolor} def
+/LT0 {PL [] LC0 DL} def
+/LT1 {PL [4 dl1 2 dl2] LC1 DL} def
+/LT2 {PL [2 dl1 3 dl2] LC2 DL} def
+/LT3 {PL [1 dl1 1.5 dl2] LC3 DL} def
+/LT4 {PL [6 dl1 2 dl2 1 dl1 2 dl2] LC4 DL} def
+/LT5 {PL [3 dl1 3 dl2 1 dl1 3 dl2] LC5 DL} def
+/LT6 {PL [2 dl1 2 dl2 2 dl1 6 dl2] LC6 DL} def
+/LT7 {PL [1 dl1 2 dl2 6 dl1 2 dl2 1 dl1 2 dl2] LC7 DL} def
+/LT8 {PL [2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 2 dl2 2 dl1 4 dl2] LC8 DL} def
+/Pnt {stroke [] 0 setdash gsave 1 setlinecap M 0 0 V stroke grestore} def
+/Dia {stroke [] 0 setdash 2 copy vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke
+  Pnt} def
+/Pls {stroke [] 0 setdash vpt sub M 0 vpt2 V
+  currentpoint stroke M
+  hpt neg vpt neg R hpt2 0 V stroke
+ } def
+/Box {stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke
+  Pnt} def
+/Crs {stroke [] 0 setdash exch hpt sub exch vpt add M
+  hpt2 vpt2 neg V currentpoint stroke M
+  hpt2 neg 0 R hpt2 vpt2 V stroke} def
+/TriU {stroke [] 0 setdash 2 copy vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke
+  Pnt} def
+/Star {2 copy Pls Crs} def
+/BoxF {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath fill} def
+/TriUF {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath fill} def
+/TriD {stroke [] 0 setdash 2 copy vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke
+  Pnt} def
+/TriDF {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath fill} def
+/DiaF {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath fill} def
+/Pent {stroke [] 0 setdash 2 copy gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore Pnt} def
+/PentF {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath fill grestore} def
+/Circle {stroke [] 0 setdash 2 copy
+  hpt 0 360 arc stroke Pnt} def
+/CircleF {stroke [] 0 setdash hpt 0 360 arc fill} def
+/C0 {BL [] 0 setdash 2 copy moveto vpt 90 450 arc} bind def
+/C1 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C2 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C3 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C4 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C5 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc
+	2 copy moveto
+	2 copy vpt 180 270 arc closepath fill
+	vpt 0 360 arc} bind def
+/C6 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C7 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 270 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C8 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C9 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 270 450 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C10 {BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill
+	2 copy moveto
+	2 copy vpt 90 180 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C11 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 180 arc closepath fill
+	2 copy moveto
+	2 copy vpt 270 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C12 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C13 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 0 90 arc closepath fill
+	2 copy moveto
+	2 copy vpt 180 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/C14 {BL [] 0 setdash 2 copy moveto
+	2 copy vpt 90 360 arc closepath fill
+	vpt 0 360 arc} bind def
+/C15 {BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill
+	vpt 0 360 arc closepath} bind def
+/Rec {newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+	neg 0 rlineto closepath} bind def
+/Square {dup Rec} bind def
+/Bsquare {vpt sub exch vpt sub exch vpt2 Square} bind def
+/S0 {BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare} bind def
+/S1 {BL [] 0 setdash 2 copy vpt Square fill Bsquare} bind def
+/S2 {BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S3 {BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare} bind def
+/S4 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S5 {BL [] 0 setdash 2 copy 2 copy vpt Square fill
+	exch vpt sub exch vpt sub vpt Square fill Bsquare} bind def
+/S6 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S7 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S8 {BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare} bind def
+/S9 {BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare} bind def
+/S10 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill
+	Bsquare} bind def
+/S11 {BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill
+	Bsquare} bind def
+/S12 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare} bind def
+/S13 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy vpt Square fill Bsquare} bind def
+/S14 {BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill
+	2 copy exch vpt sub exch vpt Square fill Bsquare} bind def
+/S15 {BL [] 0 setdash 2 copy Bsquare fill Bsquare} bind def
+/D0 {gsave translate 45 rotate 0 0 S0 stroke grestore} bind def
+/D1 {gsave translate 45 rotate 0 0 S1 stroke grestore} bind def
+/D2 {gsave translate 45 rotate 0 0 S2 stroke grestore} bind def
+/D3 {gsave translate 45 rotate 0 0 S3 stroke grestore} bind def
+/D4 {gsave translate 45 rotate 0 0 S4 stroke grestore} bind def
+/D5 {gsave translate 45 rotate 0 0 S5 stroke grestore} bind def
+/D6 {gsave translate 45 rotate 0 0 S6 stroke grestore} bind def
+/D7 {gsave translate 45 rotate 0 0 S7 stroke grestore} bind def
+/D8 {gsave translate 45 rotate 0 0 S8 stroke grestore} bind def
+/D9 {gsave translate 45 rotate 0 0 S9 stroke grestore} bind def
+/D10 {gsave translate 45 rotate 0 0 S10 stroke grestore} bind def
+/D11 {gsave translate 45 rotate 0 0 S11 stroke grestore} bind def
+/D12 {gsave translate 45 rotate 0 0 S12 stroke grestore} bind def
+/D13 {gsave translate 45 rotate 0 0 S13 stroke grestore} bind def
+/D14 {gsave translate 45 rotate 0 0 S14 stroke grestore} bind def
+/D15 {gsave translate 45 rotate 0 0 S15 stroke grestore} bind def
+/DiaE {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V closepath stroke} def
+/BoxE {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V closepath stroke} def
+/TriUE {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V closepath stroke} def
+/TriDE {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V closepath stroke} def
+/PentE {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  closepath stroke grestore} def
+/CircE {stroke [] 0 setdash 
+  hpt 0 360 arc stroke} def
+/Opaque {gsave closepath 1 setgray fill grestore 0 setgray closepath} def
+/DiaW {stroke [] 0 setdash vpt add M
+  hpt neg vpt neg V hpt vpt neg V
+  hpt vpt V hpt neg vpt V Opaque stroke} def
+/BoxW {stroke [] 0 setdash exch hpt sub exch vpt add M
+  0 vpt2 neg V hpt2 0 V 0 vpt2 V
+  hpt2 neg 0 V Opaque stroke} def
+/TriUW {stroke [] 0 setdash vpt 1.12 mul add M
+  hpt neg vpt -1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt 1.62 mul V Opaque stroke} def
+/TriDW {stroke [] 0 setdash vpt 1.12 mul sub M
+  hpt neg vpt 1.62 mul V
+  hpt 2 mul 0 V
+  hpt neg vpt -1.62 mul V Opaque stroke} def
+/PentW {stroke [] 0 setdash gsave
+  translate 0 hpt M 4 {72 rotate 0 hpt L} repeat
+  Opaque stroke grestore} def
+/CircW {stroke [] 0 setdash 
+  hpt 0 360 arc Opaque stroke} def
+/BoxFill {gsave Rec 1 setgray fill grestore} def
+/Density {
+  /Fillden exch def
+  currentrgbcolor
+  /ColB exch def /ColG exch def /ColR exch def
+  /ColR ColR Fillden mul Fillden sub 1 add def
+  /ColG ColG Fillden mul Fillden sub 1 add def
+  /ColB ColB Fillden mul Fillden sub 1 add def
+  ColR ColG ColB setrgbcolor} def
+/BoxColFill {gsave Rec PolyFill} def
+/PolyFill {gsave Density fill grestore grestore} def
+/h {rlineto rlineto rlineto gsave closepath fill grestore} bind def
+%
+% PostScript Level 1 Pattern Fill routine for rectangles
+% Usage: x y w h s a XX PatternFill
+%	x,y = lower left corner of box to be filled
+%	w,h = width and height of box
+%	  a = angle in degrees between lines and x-axis
+%	 XX = 0/1 for no/yes cross-hatch
+%
+/PatternFill {gsave /PFa [ 9 2 roll ] def
+  PFa 0 get PFa 2 get 2 div add PFa 1 get PFa 3 get 2 div add translate
+  PFa 2 get -2 div PFa 3 get -2 div PFa 2 get PFa 3 get Rec
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+  clip
+  currentlinewidth 0.5 mul setlinewidth
+  /PFs PFa 2 get dup mul PFa 3 get dup mul add sqrt def
+  0 0 M PFa 5 get rotate PFs -2 div dup translate
+  0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 M 0 PFs V} for
+  0 PFa 6 get ne {
+	0 1 PFs PFa 4 get div 1 add floor cvi
+	{PFa 4 get mul 0 2 1 roll M PFs 0 V} for
+ } if
+  stroke grestore} def
+%
+/languagelevel where
+ {pop languagelevel} {1} ifelse
+ 2 lt
+	{/InterpretLevel1 true def}
+	{/InterpretLevel1 Level1 def}
+ ifelse
+%
+% PostScript level 2 pattern fill definitions
+%
+/Level2PatternFill {
+/Tile8x8 {/PaintType 2 /PatternType 1 /TilingType 1 /BBox [0 0 8 8] /XStep 8 /YStep 8}
+	bind def
+/KeepColor {currentrgbcolor [/Pattern /DeviceRGB] setcolorspace} bind def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke} 
+>> matrix makepattern
+/Pat1 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 8 8 L 0 8 M 8 0 L stroke
+	0 4 M 4 8 L 8 4 L 4 0 L 0 4 L stroke}
+>> matrix makepattern
+/Pat2 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 0 M 0 8 L
+	8 8 L 8 0 L 0 0 L fill}
+>> matrix makepattern
+/Pat3 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 8 M 8 -4 L
+	0 12 M 12 0 L stroke}
+>> matrix makepattern
+/Pat4 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -4 0 M 8 12 L
+	0 -4 M 12 8 L stroke}
+>> matrix makepattern
+/Pat5 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 8 M 4 -4 L
+	0 12 M 8 -4 L 4 12 M 10 0 L stroke}
+>> matrix makepattern
+/Pat6 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop -2 0 M 4 12 L
+	0 -4 M 8 12 L 4 -4 M 10 8 L stroke}
+>> matrix makepattern
+/Pat7 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 8 -2 M -4 4 L
+	12 0 M -4 8 L 12 4 M 0 10 L stroke}
+>> matrix makepattern
+/Pat8 exch def
+<< Tile8x8
+ /PaintProc {0.5 setlinewidth pop 0 -2 M 12 4 L
+	-4 0 M 12 8 L -4 4 M 8 10 L stroke}
+>> matrix makepattern
+/Pat9 exch def
+/Pattern1 {PatternBgnd KeepColor Pat1 setpattern} bind def
+/Pattern2 {PatternBgnd KeepColor Pat2 setpattern} bind def
+/Pattern3 {PatternBgnd KeepColor Pat3 setpattern} bind def
+/Pattern4 {PatternBgnd KeepColor Landscape {Pat5} {Pat4} ifelse setpattern} bind def
+/Pattern5 {PatternBgnd KeepColor Landscape {Pat4} {Pat5} ifelse setpattern} bind def
+/Pattern6 {PatternBgnd KeepColor Landscape {Pat9} {Pat6} ifelse setpattern} bind def
+/Pattern7 {PatternBgnd KeepColor Landscape {Pat8} {Pat7} ifelse setpattern} bind def
+} def
+%
+%
+%End of PostScript Level 2 code
+%
+/PatternBgnd {
+  TransparentPatterns {} {gsave 1 setgray fill grestore} ifelse
+} def
+%
+% Substitute for Level 2 pattern fill codes with
+% grayscale if Level 2 support is not selected.
+%
+/Level1PatternFill {
+/Pattern1 {0.250 Density} bind def
+/Pattern2 {0.500 Density} bind def
+/Pattern3 {0.750 Density} bind def
+/Pattern4 {0.125 Density} bind def
+/Pattern5 {0.375 Density} bind def
+/Pattern6 {0.625 Density} bind def
+/Pattern7 {0.875 Density} bind def
+} def
+%
+% Now test for support of Level 2 code
+%
+Level1 {Level1PatternFill} {Level2PatternFill} ifelse
+%
+/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont
+dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall
+currentdict end definefont pop
+Level1 SuppressPDFMark or 
+{} {
+/SDict 10 dict def
+systemdict /pdfmark known not {
+  userdict /pdfmark systemdict /cleartomark get put
+} if
+SDict begin [
+  /Title (foo.eps)
+  /Subject (gnuplot plot)
+  /Creator (gnuplot 4.6 patchlevel 5)
+  /Author (kisskys)
+%  /Producer (gnuplot)
+%  /Keywords ()
+  /CreationDate (Sat Jul 11 23:19:23 2015)
+  /DOCINFO pdfmark
+end
+} ifelse
+end
+%%EndProlog
+%%Page: 1 1
+gnudict begin
+gsave
+doclip
+50 50 translate
+0.050 0.050 scale
+0 setgray
+newpath
+(Helvetica) findfont 140 scalefont setfont
+BackgroundColor 0 lt 3 1 roll 0 lt exch 0 lt or or not {BackgroundColor C 1.000 0 0 7200.00 5040.00 BoxColFill} if
+gsave % colour palette begin
+/maxcolors 0 def
+/HSV2RGB {  exch dup 0.0 eq {pop exch pop dup dup} % achromatic gray
+  { /HSVs exch def /HSVv exch def 6.0 mul dup floor dup 3 1 roll sub
+     /HSVf exch def /HSVi exch cvi def /HSVp HSVv 1.0 HSVs sub mul def
+	 /HSVq HSVv 1.0 HSVs HSVf mul sub mul def 
+	 /HSVt HSVv 1.0 HSVs 1.0 HSVf sub mul sub mul def
+	 /HSVi HSVi 6 mod def 0 HSVi eq {HSVv HSVt HSVp}
+	 {1 HSVi eq {HSVq HSVv HSVp}{2 HSVi eq {HSVp HSVv HSVt}
+	 {3 HSVi eq {HSVp HSVq HSVv}{4 HSVi eq {HSVt HSVp HSVv}
+	 {HSVv HSVp HSVq} ifelse} ifelse} ifelse} ifelse} ifelse
+  } ifelse} def
+/Constrain {
+  dup 0 lt {0 exch pop}{dup 1 gt {1 exch pop} if} ifelse} def
+/YIQ2RGB {
+  3 copy -1.702 mul exch -1.105 mul add add Constrain 4 1 roll
+  3 copy -0.647 mul exch -0.272 mul add add Constrain 5 1 roll
+  0.621 mul exch -0.956 mul add add Constrain 3 1 roll } def
+/CMY2RGB {  1 exch sub exch 1 exch sub 3 2 roll 1 exch sub 3 1 roll exch } def
+/XYZ2RGB {  3 copy -0.9017 mul exch -0.1187 mul add exch 0.0585 mul exch add
+  Constrain 4 1 roll 3 copy -0.0279 mul exch 1.999 mul add exch
+  -0.9844 mul add Constrain 5 1 roll -0.2891 mul exch -0.5338 mul add
+  exch 1.91 mul exch add Constrain 3 1 roll} def
+/SelectSpace {ColorSpace (HSV) eq {HSV2RGB}{ColorSpace (XYZ) eq {
+  XYZ2RGB}{ColorSpace (CMY) eq {CMY2RGB}{ColorSpace (YIQ) eq {YIQ2RGB}
+  if} ifelse} ifelse} ifelse} def
+/InterpolatedColor true def
+/grayindex {/gidx 0 def
+  {GrayA gidx get grayv ge {exit} if /gidx gidx 1 add def} loop} def
+/dgdx {grayv GrayA gidx get sub GrayA gidx 1 sub get
+  GrayA gidx get sub div} def 
+/redvalue {RedA gidx get RedA gidx 1 sub get
+  RedA gidx get sub dgdxval mul add} def
+/greenvalue {GreenA gidx get GreenA gidx 1 sub get
+  GreenA gidx get sub dgdxval mul add} def
+/bluevalue {BlueA gidx get BlueA gidx 1 sub get
+  BlueA gidx get sub dgdxval mul add} def
+/interpolate {
+  grayindex grayv GrayA gidx get sub abs 1e-5 le
+    {RedA gidx get GreenA gidx get BlueA gidx get}
+    {/dgdxval dgdx def redvalue greenvalue bluevalue} ifelse} def
+/GrayA [0 .2 .4 .6 .8 1 ] def
+/RedA [1 1 .8 .8 .8 1 ] def
+/GreenA [.8 .8 .8 1 1 1 ] def
+/BlueA [.8 1 1 1 .8 .8 ] def
+/pm3dround {maxcolors 0 gt {dup 1 ge
+	{pop 1} {maxcolors mul floor maxcolors 1 sub div} ifelse} if} def
+/pm3dGamma 1.0 1.5 Gamma mul div def
+/ColorSpace (RGB) def
+Color InterpolatedColor or { % COLOUR vs. GRAY map
+  InterpolatedColor { %% Interpolation vs. RGB-Formula
+    /g {stroke pm3dround /grayv exch def interpolate
+        SelectSpace setrgbcolor} bind def
+  }{
+  /g {stroke pm3dround dup cF7 Constrain exch dup cF5 Constrain exch cF15 Constrain 
+       SelectSpace setrgbcolor} bind def
+  } ifelse
+}{
+  /g {stroke pm3dround pm3dGamma exp setgray} bind def
+} ifelse
+1.000 UL
+LTb
+LCb setrgbcolor
+378 1277 M
+63 0 V
+5687 0 R
+-63 0 V
+-5771 0 R
+(S2) Rshow
+1.000 UL
+LTb
+LCb setrgbcolor
+378 2660 M
+63 0 V
+5687 0 R
+-63 0 V
+-5771 0 R
+(A) Rshow
+1.000 UL
+LTb
+LCb setrgbcolor
+378 4042 M
+63 0 V
+5687 0 R
+-63 0 V
+-5771 0 R
+(S0) Rshow
+1.000 UL
+LTb
+LCb setrgbcolor
+1.000 UL
+LTa
+LCa setrgbcolor
+378 448 M
+0 4423 V
+stroke
+LTb
+LCb setrgbcolor
+378 448 M
+0 63 V
+0 4360 R
+0 -63 V
+378 308 M
+( 0) Cshow
+1.000 UL
+LTb
+LCb setrgbcolor
+1.000 UL
+LTa
+LCa setrgbcolor
+1336 448 M
+0 4423 V
+stroke
+LTb
+LCb setrgbcolor
+1336 448 M
+0 63 V
+0 4360 R
+0 -63 V
+0 -4500 R
+( 5) Cshow
+1.000 UL
+LTb
+LCb setrgbcolor
+1.000 UL
+LTa
+LCa setrgbcolor
+2295 448 M
+0 4423 V
+stroke
+LTb
+LCb setrgbcolor
+2295 448 M
+0 63 V
+0 4360 R
+0 -63 V
+0 -4500 R
+( 10) Cshow
+1.000 UL
+LTb
+LCb setrgbcolor
+1.000 UL
+LTa
+LCa setrgbcolor
+3253 448 M
+0 4423 V
+stroke
+LTb
+LCb setrgbcolor
+3253 448 M
+0 63 V
+0 4360 R
+0 -63 V
+0 -4500 R
+( 15) Cshow
+1.000 UL
+LTb
+LCb setrgbcolor
+1.000 UL
+LTa
+LCa setrgbcolor
+4211 448 M
+0 4423 V
+stroke
+LTb
+LCb setrgbcolor
+4211 448 M
+0 63 V
+0 4360 R
+0 -63 V
+0 -4500 R
+( 20) Cshow
+1.000 UL
+LTb
+LCb setrgbcolor
+1.000 UL
+LTa
+LCa setrgbcolor
+5170 448 M
+0 4423 V
+stroke
+LTb
+LCb setrgbcolor
+5170 448 M
+0 63 V
+0 4360 R
+0 -63 V
+0 -4500 R
+( 25) Cshow
+1.000 UL
+LTb
+LCb setrgbcolor
+1.000 UL
+LTa
+LCa setrgbcolor
+6128 448 M
+0 4423 V
+stroke
+LTb
+LCb setrgbcolor
+6128 448 M
+0 63 V
+0 4360 R
+0 -63 V
+0 -4500 R
+( 30) Cshow
+1.000 UL
+LTb
+LCb setrgbcolor
+1.000 UL
+LTb
+LCb setrgbcolor
+378 4871 N
+378 448 L
+5750 0 V
+0 4423 V
+-5750 0 V
+Z stroke
+LCb setrgbcolor
+112 2659 M
+currentpoint gsave translate -270 rotate 0 0 M
+() Cshow
+grestore
+LTb
+LCb setrgbcolor
+3253 98 M
+(time) Cshow
+LTb
+3253 4801 M
+() Cshow
+1.000 UL
+LTb
+0 g 0.800 378 3489 575 1106 BoxColFill
+LCb setrgbcolor
+378 3489 M
+0 1106 V
+575 0 V
+0 -1106 V
+-575 0 V
+stroke
+LTb
+0 g 0.800 953 2107 383 1105 BoxColFill
+LCb setrgbcolor
+953 2107 M
+0 1105 V
+383 0 V
+0 -1105 V
+-383 0 V
+stroke
+LTb
+.2 g 0.800 1145 3489 575 1106 BoxColFill
+LCb setrgbcolor
+1145 3489 M
+0 1106 V
+575 0 V
+0 -1106 V
+-575 0 V
+stroke
+LTb
+0 g 0.800 1336 724 575 1106 BoxColFill
+LCb setrgbcolor
+1336 724 M
+0 1106 V
+575 0 V
+0 -1106 V
+-575 0 V
+stroke
+LTb
+.2 g 0.800 1720 2107 766 1105 BoxColFill
+LCb setrgbcolor
+1720 2107 M
+0 1105 V
+766 0 V
+0 -1105 V
+-766 0 V
+stroke
+LTb
+.4 g 0.800 1911 3489 575 1106 BoxColFill
+LCb setrgbcolor
+1911 3489 M
+0 1106 V
+575 0 V
+0 -1106 V
+-575 0 V
+stroke
+LTb
+.2 g 0.800 2486 724 575 1106 BoxColFill
+LCb setrgbcolor
+2486 724 M
+0 1106 V
+575 0 V
+0 -1106 V
+-575 0 V
+stroke
+LTb
+.4 g 0.800 2486 2107 575 1105 BoxColFill
+LCb setrgbcolor
+2486 2107 M
+0 1105 V
+575 0 V
+0 -1105 V
+-575 0 V
+stroke
+LTb
+.6 g 0.800 2678 3489 575 1106 BoxColFill
+LCb setrgbcolor
+2678 3489 M
+0 1106 V
+575 0 V
+0 -1106 V
+-575 0 V
+stroke
+LTb
+.4 g 0.800 3061 724 575 1106 BoxColFill
+LCb setrgbcolor
+3061 724 M
+0 1106 V
+575 0 V
+0 -1106 V
+-575 0 V
+stroke
+LTb
+.6 g 0.800 3253 2107 767 1105 BoxColFill
+LCb setrgbcolor
+3253 2107 M
+0 1105 V
+767 0 V
+0 -1105 V
+-767 0 V
+stroke
+LTb
+.8 g 0.800 3445 3489 575 1106 BoxColFill
+LCb setrgbcolor
+3445 3489 M
+0 1106 V
+575 0 V
+0 -1106 V
+-575 0 V
+stroke
+LTb
+.6 g 0.800 4020 724 575 1106 BoxColFill
+LCb setrgbcolor
+4020 724 M
+0 1106 V
+575 0 V
+0 -1106 V
+-575 0 V
+stroke
+LTb
+.8 g 0.800 4020 2107 575 1105 BoxColFill
+LCb setrgbcolor
+4020 2107 M
+0 1105 V
+575 0 V
+0 -1105 V
+-575 0 V
+stroke
+LTb
+1 g 0.800 4211 3489 575 1106 BoxColFill
+LCb setrgbcolor
+4211 3489 M
+0 1106 V
+575 0 V
+0 -1106 V
+-575 0 V
+stroke
+LTb
+.8 g 0.800 4595 724 575 1106 BoxColFill
+LCb setrgbcolor
+4595 724 M
+0 1106 V
+575 0 V
+0 -1106 V
+-575 0 V
+stroke
+LTb
+1 g 0.800 4786 2107 767 1105 BoxColFill
+LCb setrgbcolor
+4786 2107 M
+0 1105 V
+767 0 V
+0 -1105 V
+-767 0 V
+stroke
+LTb
+1 g 0.800 5553 724 574 1106 BoxColFill
+LCb setrgbcolor
+5553 724 M
+0 1106 V
+574 0 V
+0 -1106 V
+-574 0 V
+1.000 UP
+stroke
+LTb
+LCb setrgbcolor
+% Begin plot #1
+6.000 UL
+LT0
+0 g LCb setrgbcolor
+6548 4801 M
+(0) Rshow
+LT0
+0 g 6632 4801 M
+399 0 V
+% End plot #1
+% Begin plot #2
+stroke
+LT1
+.2 g LCb setrgbcolor
+6548 4661 M
+(1) Rshow
+LT1
+.2 g 6632 4661 M
+399 0 V
+% End plot #2
+% Begin plot #3
+stroke
+LT2
+.4 g LCb setrgbcolor
+6548 4521 M
+(2) Rshow
+LT2
+.4 g 6632 4521 M
+399 0 V
+% End plot #3
+% Begin plot #4
+stroke
+LT3
+.6 g LCb setrgbcolor
+6548 4381 M
+(3) Rshow
+LT3
+.6 g 6632 4381 M
+399 0 V
+% End plot #4
+% Begin plot #5
+stroke
+LT4
+.8 g LCb setrgbcolor
+6548 4241 M
+(4) Rshow
+LT4
+.8 g 6632 4241 M
+399 0 V
+% End plot #5
+% Begin plot #6
+stroke
+LT5
+1 g LCb setrgbcolor
+6548 4101 M
+(5) Rshow
+LT5
+1 g 6632 4101 M
+399 0 V
+% End plot #6
+stroke
+1.000 UL
+LTb
+LCb setrgbcolor
+378 4871 N
+378 448 L
+5750 0 V
+0 4423 V
+-5750 0 V
+Z stroke
+1.000 UP
+1.000 UL
+LTb
+LCb setrgbcolor
+grestore % colour palette end
+stroke
+grestore
+end
+showpage
+%%Trailer
+%%DocumentFonts: Helvetica
diff --git a/asterix-experiments/src/main/resources/gantt/foo.gpl b/asterix-experiments/src/main/resources/gantt/foo.gpl
new file mode 100644
index 0000000..d1e62bf
--- /dev/null
+++ b/asterix-experiments/src/main/resources/gantt/foo.gpl
@@ -0,0 +1,35 @@
+set xrange [0.000000:30.000000]
+set yrange [0.400000:3.600000]
+set autoscale x
+set xlabel "time"
+set ylabel ""
+set title ""
+set ytics ("A" 2, "S2" 1, "S0" 3)
+set key outside width +2
+set grid xtics
+set palette model RGB defined ( 0 1.0 0.8 0.8, 1 1.0 0.8 1.0, 2 0.8 0.8 1.0, 3 0.8 1.0 1.0, 4 0.8 1.0 0.8, 5 1.0 1.0 0.8 )
+unset colorbox
+set object 1 rectangle from 0.000000, 2.6 to 3.000000, 3.4 fillcolor palette frac 0.00 fillstyle solid 0.8
+set object 2 rectangle from 3.000000, 1.6 to 5.000000, 2.4 fillcolor palette frac 0.00 fillstyle solid 0.8
+set object 3 rectangle from 4.000000, 2.6 to 7.000000, 3.4 fillcolor palette frac 0.20 fillstyle solid 0.8
+set object 4 rectangle from 5.000000, 0.6 to 8.000000, 1.4 fillcolor palette frac 0.00 fillstyle solid 0.8
+set object 5 rectangle from 7.000000, 1.6 to 11.000000, 2.4 fillcolor palette frac 0.20 fillstyle solid 0.8
+set object 6 rectangle from 8.000000, 2.6 to 11.000000, 3.4 fillcolor palette frac 0.40 fillstyle solid 0.8
+set object 7 rectangle from 11.000000, 0.6 to 14.000000, 1.4 fillcolor palette frac 0.20 fillstyle solid 0.8
+set object 8 rectangle from 11.000000, 1.6 to 14.000000, 2.4 fillcolor palette frac 0.40 fillstyle solid 0.8
+set object 9 rectangle from 12.000000, 2.6 to 15.000000, 3.4 fillcolor palette frac 0.60 fillstyle solid 0.8
+set object 10 rectangle from 14.000000, 0.6 to 17.000000, 1.4 fillcolor palette frac 0.40 fillstyle solid 0.8
+set object 11 rectangle from 15.000000, 1.6 to 19.000000, 2.4 fillcolor palette frac 0.60 fillstyle solid 0.8
+set object 12 rectangle from 16.000000, 2.6 to 19.000000, 3.4 fillcolor palette frac 0.80 fillstyle solid 0.8
+set object 13 rectangle from 19.000000, 0.6 to 22.000000, 1.4 fillcolor palette frac 0.60 fillstyle solid 0.8
+set object 14 rectangle from 19.000000, 1.6 to 22.000000, 2.4 fillcolor palette frac 0.80 fillstyle solid 0.8
+set object 15 rectangle from 20.000000, 2.6 to 23.000000, 3.4 fillcolor palette frac 1.00 fillstyle solid 0.8
+set object 16 rectangle from 22.000000, 0.6 to 25.000000, 1.4 fillcolor palette frac 0.80 fillstyle solid 0.8
+set object 17 rectangle from 23.000000, 1.6 to 27.000000, 2.4 fillcolor palette frac 1.00 fillstyle solid 0.8
+set object 18 rectangle from 27.000000, 0.6 to 30.000000, 1.4 fillcolor palette frac 1.00 fillstyle solid 0.8
+plot -1 title "0" with lines linecolor palette frac 0.00  linewidth 6, \
+	-1 title "1" with lines linecolor palette frac 0.20  linewidth 6, \
+	-1 title "2" with lines linecolor palette frac 0.40  linewidth 6, \
+	-1 title "3" with lines linecolor palette frac 0.60  linewidth 6, \
+	-1 title "4" with lines linecolor palette frac 0.80  linewidth 6, \
+	-1 title "5" with lines linecolor palette frac 1.00  linewidth 6
\ No newline at end of file
diff --git a/asterix-experiments/src/main/resources/gantt/gantt.py b/asterix-experiments/src/main/resources/gantt/gantt.py
new file mode 100644
index 0000000..faf9e94
--- /dev/null
+++ b/asterix-experiments/src/main/resources/gantt/gantt.py
@@ -0,0 +1,387 @@
+#!/usr/bin/env python
+#
+# TODO:
+# - Task colors:
+#     - User-defined using config file.
+#     - Automagically chosen from color space.
+#     - Advanced algorithm (contact Hannes Pretorius).
+# - Koos' specs:
+#     - Resources and tasks sorted in read-in order (default)
+#       or alphabetically (flag).
+#     - Have proper gnuplot behavior on windows/x11, eps/pdf, latex terminals.
+#     - Create and implement algorithm for critical path analysis.
+# - Split generic stuff into a Gantt class, and specific stuff into the main.
+#
+# gantt.py ganttfile | gnuplot
+
+import itertools, sys, getopt
+from ConfigParser import ConfigParser
+
+rectangleHeight = 0.8  #: Height of a rectangle in units.
+
+class Activity(object):
+    """
+    Container for activity information.
+
+    @ivar resource: Resource name.
+    @type resource: C{str}
+
+    @ivar start: Start time of the activity.
+    @type start: C{float}
+
+    @ivar stop: End time of the activity.
+    @type stop: C{float}
+
+    @ivar task: Name of the task/activity being performed.
+    @type task: C{str}
+    """
+    def __init__(self, resource, start, stop, task):
+        self.resource = resource
+        self.start = start
+        self.stop = stop
+        self.task = task
+
+class Rectangle(object):
+    """
+    Container for rectangle information.
+    """
+    def __init__(self, bottomleft, topright, fillcolor):
+        self.bottomleft = bottomleft
+        self.topright = topright
+        self.fillcolor = fillcolor
+        self.fillstyle = 'solid 0.8'
+        self.linewidth = 2
+
+class ColorBook(object):
+    """
+    Class managing colors.
+
+    @ivar colors
+    @ivar palette
+    @ivar prefix
+    """
+    def __init__(self, colorfname, tasks):
+        """
+        Construct a ColorBook object.
+
+        @param colorfname: Name of the color config file (if specified).
+        @type  colorfname: C{str} or C{None}
+
+        @param tasks: Existing task types.
+        @type  tasks: C{list} of C{str}
+        """
+        if colorfname:
+            values = self.load_config(colorfname, tasks)
+        else:
+            values = self.fixed(tasks)
+
+        self.colors, self.palette, self.prefix = values
+
+
+    def load_config(self, colorfname, tasks):
+        """
+        Read task colors from a configuration file.
+        """
+        palettedef = 'model RGB'
+        colorprefix = 'rgb'
+
+        # Read in task colors from configuration file
+        config = ConfigParser()
+        config.optionxform = str # makes option names case sensitive
+        config.readfp(open(colorfname, 'r'))
+        # Colors are RGB colornames
+        colors = dict(config.items('Colors'))
+
+        # Raise KeyError if no color is specified for a task
+        nocolors = [t for t in tasks if not colors.has_key(t)]
+        if nocolors:
+            msg = 'Could not find task color for ' + ', '.join(nocolors)
+            raise KeyError(msg)
+
+        return colors, palettedef, colorprefix
+
+    def fixed(self, tasks):
+        """
+        Pick colors from a pre-defined palette.
+        """
+        # Set task colors
+        # SE colors
+        # (see http://w3.wtb.tue.nl/nl/organisatie/systems_engineering/\
+        #      info_for_se_students/how2make_a_poster/pictures/)
+        # Decrease the 0.8 values for less transparent colors.
+        se_palette = {"se_red":   (1.0, 0.8, 0.8),
+                     "se_pink":   (1.0, 0.8, 1.0),
+                     "se_violet": (0.8, 0.8, 1.0),
+                     "se_blue":   (0.8, 1.0, 1.0),
+                     "se_green":  (0.8, 1.0, 0.8),
+                     "se_yellow": (1.0, 1.0, 0.8)}
+        se_gradient = ["se_red", "se_pink", "se_violet",
+                       "se_blue", "se_green", "se_yellow"]
+        se_palettedef = '( ' + \
+                        ', '.join(('%d ' % n +
+                                   ' '.join((str(x) for x in se_palette[c]))
+                                   for n, c in enumerate(se_gradient))) + \
+                        ' )'
+
+        palettedef = 'model RGB defined %s' % se_palettedef
+        colorprefix = 'palette frac'
+        # Colors are fractions from the palette defined
+        colors = dict((t, '%0.2f' % (float(n)/(len(tasks)-1)))
+                       for n, t in enumerate(tasks))
+
+        return colors, palettedef, colorprefix
+
+class DummyClass(object):
+    """
+    Dummy class for storing option values in.
+    """
+
+
+def make_rectangles(activities, resource_map, colors):
+    """
+    Construct a collection of L{Rectangle} for all activities.
+
+    @param activities: Activities being performed.
+    @type  activities: C{iterable} of L{Activity}
+
+    @param resource_map: Indices of all resources.
+    @type  resource_map: C{dict} of C{str} to C{int}
+
+    @param colors: Colors for all tasks.
+    @type  colors: C{dict} of C{str} to C{str}
+
+    @return: Collection of rectangles to draw.
+    @rtype:  C{list} of L{Rectangle}
+    """
+    rectangles = []
+    for act in activities:
+        ypos = resource_map[act.resource]
+        bottomleft = (act.start, ypos - 0.5 * rectangleHeight)
+        topright = (act.stop, ypos + 0.5 * rectangleHeight)
+        fillcolor = colors[act.task]
+        rectangles.append(Rectangle(bottomleft, topright, fillcolor))
+
+    return rectangles
+
+
+def load_ganttfile(ganttfile):
+    """
+    Load the resource/task file.
+
+    @param ganttfile: Name of the gantt file.
+    @type  ganttfile: C{str}
+
+    @return: Activities loaded from the file, collection of
+             (resource, start, end, task) activities.
+    @rtype:  C{list} of L{Activity}
+    """
+    activities = []
+    for line in open(ganttfile, 'r').readlines():
+        line = line.strip().split()
+        if len(line) == 0:
+            continue
+        resource = line[0]
+        start = float(line[1])
+        stop = float(line[2])
+        task = line[3]
+        activities.append(Activity(resource, start, stop, task))
+
+    return activities
+
+def make_unique_tasks_resources(alphasort, activities):
+    """
+    Construct collections of unique task names and resource names.
+
+    @param alphasort: Sort resources and tasks alphabetically.
+    @type  alphasort: C{bool}
+
+    @param activities: Activities to draw.
+    @type  activities: C{list} of L{Activity}
+
+    @return: Collections of task-types and resources.
+    @rtype:  C{list} of C{str}, C{list} of C{str}
+    """
+    # Create list with unique resources and tasks in activity order.
+    resources = []
+    tasks = []
+    for act in activities:
+        if act.resource not in resources:
+            resources.append(act.resource)
+        if act.task not in tasks:
+            tasks.append(act.task)
+
+    # Sort such that resources and tasks appear in alphabetical order
+    if alphasort:
+        resources.sort()
+        tasks.sort()
+
+    # Resources are read from top (y=max) to bottom (y=1)
+    resources.reverse()
+
+    return tasks, resources
+
+
+def generate_plotdata(activities, resources, tasks, rectangles, options,
+                     resource_map, color_book):
+    """
+    Generate Gnuplot lines.
+    """
+    xmin = 0
+    xmax = max(act.stop for act in activities)
+    ymin = 0 + (rectangleHeight / 2)
+    ymax = len(resources) + 1 - (rectangleHeight / 2)
+    xlabel = 'time'
+    ylabel = ''
+    title = options.plottitle
+    ytics = ''.join(['(',
+                     ', '.join(('"%s" %d' % item)
+                                for item in resource_map.iteritems()),
+                     ')'])
+    # outside and 2 characters from the graph
+    key_position = 'outside width +2'
+    grid_tics = 'xtics'
+
+    # Set plot dimensions
+    plot_dimensions = ['set xrange [%f:%f]' % (xmin, xmax),
+                       'set yrange [%f:%f]' % (ymin, ymax),
+                       'set autoscale x', # extends x axis to next tic mark
+                       'set xlabel "%s"' % xlabel,
+                       'set ylabel "%s"' % ylabel,
+                       'set title "%s"' % title,
+                       'set ytics %s' % ytics,
+                       'set key %s' % key_position,
+                       'set grid %s' % grid_tics,
+                       'set palette %s' % color_book.palette,
+                       'unset colorbox']
+
+    # Generate gnuplot rectangle objects
+    plot_rectangles = (' '.join(['set object %d rectangle' % n,
+                                 'from %f, %0.1f' % r.bottomleft,
+                                 'to %f, %0.1f' % r.topright,
+                                 'fillcolor %s %s' % (color_book.prefix,
+                                                      r.fillcolor),
+                                 'fillstyle solid 0.8'])
+                    for n, r in itertools.izip(itertools.count(1), rectangles))
+
+    # Generate gnuplot lines
+    plot_lines = ['plot ' +
+                  ', \\\n\t'.join(' '.join(['-1',
+                                      'title "%s"' % t,
+                                      'with lines',
+                                      'linecolor %s %s ' % (color_book.prefix,
+                                                        color_book.colors[t]),
+                                      'linewidth 6'])
+                            for t in tasks)]
+
+    return plot_dimensions, plot_rectangles, plot_lines
+
+def write_data(plot_dimensions, plot_rectangles, plot_lines, fname):
+    """
+    Write plot data out to file or screen.
+
+    @param fname: Name of the output file, if specified.
+    @type  fname: C{str}  (??)
+    """
+    if fname:
+        g = open(fname, 'w')
+        g.write('\n'.join(itertools.chain(plot_dimensions, plot_rectangles,
+                                          plot_lines)))
+        g.close()
+    else:
+        print '\n'.join(itertools.chain(plot_dimensions, plot_rectangles,
+                                        plot_lines))
+
+def fmt_opt(short, long, arg, text):
+    if arg:
+        return '-%s %s, --%s%s\t%s' % (short[:-1], arg, long, arg, text)
+    else:
+        return '-%s, --%s\t%s' % (short, long, text)
+
+def make_default_options():
+    option_values = DummyClass()
+    option_values.outputfile = ''
+    option_values.colorfile = ''
+    option_values.alphasort = False
+    option_values.plottitle = ''
+    return option_values
+
+def process_options():
+    """
+    Handle option and command-line argument processing.
+
+    @return: Options and gantt input filename.
+    @rtype:  L{OptionParser} options, C{str}
+    """
+    optdefs = [('o:', 'output=', 'FILE', 'Write output to FILE.'),
+               ('c:', 'color=',  'FILE', 'Use task colors (RGB) as defined in '
+                'configuration FILE (in RGB triplets,\n\t\t\t\tGnuplot '
+                'colornames, or hexadecimal representations.'),
+               ('a', 'alpha', '', '\t\tShow resources and tasks in '
+                'alphabetical order.'),
+               ('t:','title=', 'TITLE', 'Set plot title to TITLE (between '
+                'double quotes).'),
+               ('h', 'help', '', '\t\tShow online help.')]
+    short_opts = ''.join(opt[0] for opt in optdefs if opt[0])
+    long_opts  = [opt[1] for opt in optdefs if opt[1]]
+    usage_text = 'gantt.py [options] gantt-file\nwhere\n' + \
+            '\n'.join('    ' + fmt_opt(*opt) for opt in optdefs)
+
+    option_values = make_default_options()
+
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], short_opts, long_opts)
+    except getopt.GetoptError, err:
+        sys.stderr.write("gantt.py: %s\n" % err)
+        sys.exit(2)
+
+    for opt, optval in opts:
+        if opt in ('-o', '--output'):
+            option_values.outputfile = optval
+            continue
+        if opt in ('-c', '--color'):
+            option_values.colorfile = optval
+            continue
+        if opt in ('-a', '--alphasort'):
+            option_values.alphasort = True
+            continue
+        if opt in ('-t', '--title'):
+            option_values.plottitle = optval
+            continue
+        if opt in ('-h', '--help'):
+            print usage_text
+            sys.exit(0)
+
+    # Check if correct number of arguments is supplied
+    if len(args) != 1:
+        sys.stderr.write('gantty.py: incorrect number of arguments '
+                         '(task/resource file expected)\n')
+        sys.exit(1)
+
+    return option_values, args[0]
+
+def compute(options, ganttfile):
+    activities = load_ganttfile(ganttfile)
+    tasks, resources = make_unique_tasks_resources(options.alphasort,
+                                                   activities)
+
+    # Assign indices to resources
+    resource_map = dict(itertools.izip(resources, itertools.count(1)))
+
+    color_book = ColorBook(options.colorfile, tasks)
+    rectangles = make_rectangles(activities, resource_map, color_book.colors)
+
+    plot_dims, plot_rects, plot_lines = \
+            generate_plotdata(activities, resources, tasks, rectangles,
+                              options, resource_map, color_book)
+
+    write_data(plot_dims, plot_rects, plot_lines, options.outputfile)
+
+def run():
+    options, ganttfile = process_options()
+    compute(options, ganttfile)
+
+
+if __name__ == '__main__':
+    run()
+
+
diff --git a/asterix-experiments/src/main/resources/gantt/vargantt1.gpl b/asterix-experiments/src/main/resources/gantt/vargantt1.gpl
new file mode 100644
index 0000000..02ac5e3
--- /dev/null
+++ b/asterix-experiments/src/main/resources/gantt/vargantt1.gpl
@@ -0,0 +1,35 @@
+set xrange [0.000000:30.000000]
+set yrange [0.400000:3.600000]
+set autoscale x
+set xlabel "time"
+set ylabel ""
+set title "Gantt chart"
+set ytics ("A" 2, "S2" 1, "S0" 3)
+set key outside width +2
+set grid xtics
+set palette model RGB
+unset colorbox
+set object 1 rectangle from 0.000000, 2.6 to 3.000000, 3.4 fillcolor rgb "#0092B5" fillstyle solid 0.8
+set object 2 rectangle from 3.000000, 1.6 to 5.000000, 2.4 fillcolor rgb "#0092B5" fillstyle solid 0.8
+set object 3 rectangle from 4.000000, 2.6 to 7.000000, 3.4 fillcolor rgb "#00AC82" fillstyle solid 0.8
+set object 4 rectangle from 5.000000, 0.6 to 8.000000, 1.4 fillcolor rgb "#0092B5" fillstyle solid 0.8
+set object 5 rectangle from 7.000000, 1.6 to 11.000000, 2.4 fillcolor rgb "#00AC82" fillstyle solid 0.8
+set object 6 rectangle from 8.000000, 2.6 to 11.000000, 3.4 fillcolor rgb "#84D200" fillstyle solid 0.8
+set object 7 rectangle from 11.000000, 0.6 to 14.000000, 1.4 fillcolor rgb "#00AC82" fillstyle solid 0.8
+set object 8 rectangle from 11.000000, 1.6 to 14.000000, 2.4 fillcolor rgb "#84D200" fillstyle solid 0.8
+set object 9 rectangle from 12.000000, 2.6 to 15.000000, 3.4 fillcolor rgb "#CEDF00" fillstyle solid 0.8
+set object 10 rectangle from 14.000000, 0.6 to 17.000000, 1.4 fillcolor rgb "#84D200" fillstyle solid 0.8
+set object 11 rectangle from 15.000000, 1.6 to 19.000000, 2.4 fillcolor rgb "#CEDF00" fillstyle solid 0.8
+set object 12 rectangle from 16.000000, 2.6 to 19.000000, 3.4 fillcolor rgb "#FFDD00" fillstyle solid 0.8
+set object 13 rectangle from 19.000000, 0.6 to 22.000000, 1.4 fillcolor rgb "#CEDF00" fillstyle solid 0.8
+set object 14 rectangle from 19.000000, 1.6 to 22.000000, 2.4 fillcolor rgb "#FFDD00" fillstyle solid 0.8
+set object 15 rectangle from 20.000000, 2.6 to 23.000000, 3.4 fillcolor rgb "#FF9A00" fillstyle solid 0.8
+set object 16 rectangle from 22.000000, 0.6 to 25.000000, 1.4 fillcolor rgb "#FFDD00" fillstyle solid 0.8
+set object 17 rectangle from 23.000000, 1.6 to 27.000000, 2.4 fillcolor rgb "#FF9A00" fillstyle solid 0.8
+set object 18 rectangle from 27.000000, 0.6 to 30.000000, 1.4 fillcolor rgb "#FF9A00" fillstyle solid 0.8
+plot -1 title "0" with lines linecolor rgb "#0092B5"  linewidth 6, \
+	-1 title "1" with lines linecolor rgb "#00AC82"  linewidth 6, \
+	-1 title "2" with lines linecolor rgb "#84D200"  linewidth 6, \
+	-1 title "3" with lines linecolor rgb "#CEDF00"  linewidth 6, \
+	-1 title "4" with lines linecolor rgb "#FFDD00"  linewidth 6, \
+	-1 title "5" with lines linecolor rgb "#FF9A00"  linewidth 6
\ No newline at end of file
diff --git a/asterix-experiments/src/main/resources/gantt/vargantt1.plt b/asterix-experiments/src/main/resources/gantt/vargantt1.plt
new file mode 100644
index 0000000..7f48291
--- /dev/null
+++ b/asterix-experiments/src/main/resources/gantt/vargantt1.plt
@@ -0,0 +1,4 @@
+set terminal postscript eps color solid
+set output "foo.eps"
+load "foo.gpl"
+unset output
diff --git a/asterix-experiments/src/main/resources/gantt/vargantt1.txt b/asterix-experiments/src/main/resources/gantt/vargantt1.txt
new file mode 100644
index 0000000..26a5641
--- /dev/null
+++ b/asterix-experiments/src/main/resources/gantt/vargantt1.txt
@@ -0,0 +1,18 @@
+S0	0.00000000000000000000	3.00000000000000000000	0
+A	3.00000000000000000000	5.00000000000000000000	0
+S0	4.00000000000000000000	7.00000000000000000000	1
+S2	5.00000000000000000000	8.00000000000000000000	0
+A	7.00000000000000000000	11.00000000000000000000	1
+S0	8.00000000000000000000	11.00000000000000000000	2
+S2	11.00000000000000000000	14.00000000000000000000	1
+A	11.00000000000000000000	14.00000000000000000000	2
+S0	12.00000000000000000000	15.00000000000000000000	3
+S2	14.00000000000000000000	17.00000000000000000000	2
+A	15.00000000000000000000	19.00000000000000000000	3
+S0	16.00000000000000000000	19.00000000000000000000	4
+S2	19.00000000000000000000	22.00000000000000000000	3
+A	19.00000000000000000000	22.00000000000000000000	4
+S0	20.00000000000000000000	23.00000000000000000000	5
+S2	22.00000000000000000000	25.00000000000000000000	4
+A	23.00000000000000000000	27.00000000000000000000	5
+S2	27.00000000000000000000	30.00000000000000000000	5
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/1.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/1.aql
new file mode 100644
index 0000000..0446799
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/1.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/2_a.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/2_a.aql
new file mode 100644
index 0000000..20e7ad5
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/2_a.aql
@@ -0,0 +1,4 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index BtreeExtraFieldIdx on Tweets(btree-extra-field1) type btree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/2_b.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/2_b.aql
new file mode 100644
index 0000000..aec3bff
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/2_b.aql
@@ -0,0 +1,4 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index RtreeLocationIdx on Tweets(sender-location) type rtree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/2_c.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/2_c.aql
new file mode 100644
index 0000000..c3ea516
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/2_c.aql
@@ -0,0 +1,4 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index InvMessageTextIdx on Tweets(message-text) type ngram(3);
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/2_d.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/2_d.aql
new file mode 100644
index 0000000..ea9eb8d
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/2_d.aql
@@ -0,0 +1,4 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index InvMessageTextIdx on Tweets(message-text) type keyword;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/3.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/3.aql
new file mode 100644
index 0000000..a143dd1
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/3.aql
@@ -0,0 +1,7 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index BtreeExtraFieldIdx on Tweets(btree-extra-field1) type btree;
+create index RtreeLocationIdx on Tweets(sender-location) type rtree;
+create index InvMessageKeywordIdx on Tweets(message-text) type keyword;
+create index InvMessagetNgramIdx on Tweets(message-text) type ngram(3);
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/4_1.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/4_1.aql
new file mode 100644
index 0000000..c3e7425
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/4_1.aql
@@ -0,0 +1,4 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index BtreeExtraFieldIdx1 on Tweets(btree-extra-field1) type btree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/4_2.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/4_2.aql
new file mode 100644
index 0000000..3f9e0d1
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/4_2.aql
@@ -0,0 +1,5 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index BtreeExtraFieldIdx1 on Tweets(btree-extra-field1) type btree;
+create index BtreeExtraFieldIdx2 on Tweets(btree-extra-field2) type btree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/4_4.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/4_4.aql
new file mode 100644
index 0000000..44f230d
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/4_4.aql
@@ -0,0 +1,7 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index BtreeExtraFieldIdx1 on Tweets(btree-extra-field1) type btree;
+create index BtreeExtraFieldIdx2 on Tweets(btree-extra-field2) type btree;
+create index BtreeExtraFieldIdx3 on Tweets(btree-extra-field3) type btree;
+create index BtreeExtraFieldIdx4 on Tweets(btree-extra-field4) type btree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/4_8.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/4_8.aql
new file mode 100644
index 0000000..f126aca
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/4_8.aql
@@ -0,0 +1,11 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index BtreeExtraFieldIdx1 on Tweets(btree-extra-field1) type btree;
+create index BtreeExtraFieldIdx2 on Tweets(btree-extra-field2) type btree;
+create index BtreeExtraFieldIdx3 on Tweets(btree-extra-field3) type btree;
+create index BtreeExtraFieldIdx4 on Tweets(btree-extra-field4) type btree;
+create index BtreeExtraFieldIdx5 on Tweets(btree-extra-field5) type btree;
+create index BtreeExtraFieldIdx6 on Tweets(btree-extra-field6) type btree;
+create index BtreeExtraFieldIdx7 on Tweets(btree-extra-field7) type btree;
+create index BtreeExtraFieldIdx8 on Tweets(btree-extra-field8) type btree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_1.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_1.aql
new file mode 100644
index 0000000..20c0d3e
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_1.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+
+create dataset Tweets1(TweetMessageType) primary key tweetid;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_1_count.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_1_count.aql
new file mode 100644
index 0000000..fab917d2
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_1_count.aql
@@ -0,0 +1,4 @@
+use dataverse experiments;
+
+let $count1 := count(for $t in dataset Tweets1 return $t.tweetid)
+return {"count1": $count1}
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_2.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_2.aql
new file mode 100644
index 0000000..5efcfc1
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_2.aql
@@ -0,0 +1,4 @@
+use dataverse experiments;
+
+create dataset Tweets1(TweetMessageType) primary key tweetid;
+create dataset Tweets2(TweetMessageType) primary key tweetid;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_2_count.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_2_count.aql
new file mode 100644
index 0000000..ce3d880
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_2_count.aql
@@ -0,0 +1,7 @@
+use dataverse experiments;
+
+let $count1 := count(for $t in dataset Tweets1 return $t.tweetid)
+return {"count1": $count1}
+
+let $count2 := count(for $t in dataset Tweets2 return $t.tweetid)
+return {"count2": $count2}
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_3.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_3.aql
new file mode 100644
index 0000000..e6d9c30
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_3.aql
@@ -0,0 +1,5 @@
+use dataverse experiments;
+
+create dataset Tweets1(TweetMessageType) primary key tweetid;
+create dataset Tweets2(TweetMessageType) primary key tweetid;
+create dataset Tweets3(TweetMessageType) primary key tweetid;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_3_count.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_3_count.aql
new file mode 100644
index 0000000..fa2c97f
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_3_count.aql
@@ -0,0 +1,10 @@
+use dataverse experiments;
+
+let $count1 := count(for $t in dataset Tweets1 return $t.tweetid)
+return {"count1": $count1}
+
+let $count2 := count(for $t in dataset Tweets2 return $t.tweetid)
+return {"count2": $count2}
+
+let $count3 := count(for $t in dataset Tweets3 return $t.tweetid)
+return {"count3": $count3}
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_4.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_4.aql
new file mode 100644
index 0000000..61d87ae
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_4.aql
@@ -0,0 +1,6 @@
+use dataverse experiments;
+
+create dataset Tweets1(TweetMessageType) primary key tweetid;
+create dataset Tweets2(TweetMessageType) primary key tweetid;
+create dataset Tweets3(TweetMessageType) primary key tweetid;
+create dataset Tweets4(TweetMessageType) primary key tweetid;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_4_count.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_4_count.aql
new file mode 100644
index 0000000..12b6210
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/5_4_count.aql
@@ -0,0 +1,13 @@
+use dataverse experiments;
+
+let $count1 := count(for $t in dataset Tweets1 return $t.tweetid)
+return {"count1": $count1}
+
+let $count2 := count(for $t in dataset Tweets2 return $t.tweetid)
+return {"count2": $count2}
+
+let $count3 := count(for $t in dataset Tweets3 return $t.tweetid)
+return {"count3": $count3}
+
+let $count4 := count(for $t in dataset Tweets4 return $t.tweetid)
+return {"count4": $count4}
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/6_a.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/6_a.aql
new file mode 100644
index 0000000..0b41bc5
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/6_a.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid using compaction policy constant(("num-components"="3"));
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/6_b.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/6_b.aql
new file mode 100644
index 0000000..ccd54d6
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/6_b.aql
@@ -0,0 +1,4 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid using compaction policy prefix(("max-mergable-component-size"="1073741824"),
+                                                                                           ("max-tolerance-component-count"="5"));
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/6_c.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/6_c.aql
new file mode 100644
index 0000000..4022943
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/6_c.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid using compaction policy constant(("num-components"="1000000"));
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_a.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_a.aql
new file mode 100644
index 0000000..0b41bc5
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_a.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid using compaction policy constant(("num-components"="3"));
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_b.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_b.aql
new file mode 100644
index 0000000..ccd54d6
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_b.aql
@@ -0,0 +1,4 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid using compaction policy prefix(("max-mergable-component-size"="1073741824"),
+                                                                                           ("max-tolerance-component-count"="5"));
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_c.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_c.aql
new file mode 100644
index 0000000..4022943
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_c.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid using compaction policy constant(("num-components"="1000000"));
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_compact.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_compact.aql
new file mode 100644
index 0000000..578f0a4
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_compact.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+
+compact dataset Tweets;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_d.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_d.aql
new file mode 100644
index 0000000..4022943
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_d.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid using compaction policy constant(("num-components"="1000000"));
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_q1.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_q1.aql
new file mode 100644
index 0000000..18b54ab
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_q1.aql
@@ -0,0 +1,8 @@
+use dataverse experiments;
+
+let $count := count(
+for $t in dataset Tweets
+where $t.tweetid = int64("1")
+return $t
+)
+return $count
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_q2.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_q2.aql
new file mode 100644
index 0000000..f691509
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/7_q2.aql
@@ -0,0 +1,8 @@
+use dataverse experiments;
+
+let $count := count(
+for $t in dataset Tweets
+where $t.tweetid >= int64("1") and $t.tweetid <= int64("1000")
+return $t
+)
+return $count
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_a.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_a.aql
new file mode 100644
index 0000000..38ee0a1
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_a.aql
@@ -0,0 +1,4 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid using compaction policy constant(("num-components"="3"));
+create index BtreeExtraFieldIdx on Tweets(btree-extra-field1) type btree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_b.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_b.aql
new file mode 100644
index 0000000..6eead85
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_b.aql
@@ -0,0 +1,5 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid using compaction policy prefix(("max-mergable-component-size"="1073741824"),
+                                                                                           ("max-tolerance-component-count"="5"));
+create index BtreeExtraFieldIdx on Tweets(btree-extra-field1) type btree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_c.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_c.aql
new file mode 100644
index 0000000..134f824
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_c.aql
@@ -0,0 +1,4 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid using compaction policy constant(("num-components"="1000000"));
+create index BtreeExtraFieldIdx on Tweets(btree-extra-field1) type btree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_compact.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_compact.aql
new file mode 100644
index 0000000..578f0a4
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_compact.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+
+compact dataset Tweets;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_d.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_d.aql
new file mode 100644
index 0000000..134f824
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_d.aql
@@ -0,0 +1,4 @@
+use dataverse experiments;
+
+create dataset Tweets(TweetMessageType) primary key tweetid using compaction policy constant(("num-components"="1000000"));
+create index BtreeExtraFieldIdx on Tweets(btree-extra-field1) type btree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_q1.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_q1.aql
new file mode 100644
index 0000000..03bebb6
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_q1.aql
@@ -0,0 +1,8 @@
+use dataverse experiments;
+
+let $count := count(
+for $t in dataset Tweets
+where $t.tweetid = int64("$KEY$")
+return $t
+)
+return {"pointLookupCount": $count}
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_q2.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_q2.aql
new file mode 100644
index 0000000..bd34067
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/8_q2.aql
@@ -0,0 +1,8 @@
+use dataverse experiments;
+
+let $count := count(
+for $t in dataset Tweets
+where $t.btree-extra-field1 > $LKEY$ and $t.btree-extra-field1 <= $HKEY$
+return $t
+)
+return {"rangeQueryCount": $count}
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/avg_gram_tokens.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/avg_gram_tokens.aql
new file mode 100644
index 0000000..2daa62f
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/avg_gram_tokens.aql
@@ -0,0 +1,6 @@
+use dataverse experiments;
+
+let $avg := avg(for $t in dataset Tweets
+let $c := count(gram-tokens($t.message-text, 3, 1))
+return $c)
+return {"avg-grams-per-record": $avg}
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/avg_keyword_tokens.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/avg_keyword_tokens.aql
new file mode 100644
index 0000000..a8dad49
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/avg_keyword_tokens.aql
@@ -0,0 +1,6 @@
+use dataverse experiments;
+
+let $avg := avg(for $t in dataset Tweets
+let $c := count(word-tokens($t.message-text))
+return $c)
+return {"avg-keywords-per-record": $avg}
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/5_1_ingest.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/5_1_ingest.aql
new file mode 100644
index 0000000..395f670
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/5_1_ingest.aql
@@ -0,0 +1,15 @@
+use dataverse experiments;
+
+create feed TweetFeed1 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10001,128.195.9.23:10001,128.195.9.24:10001,128.195.9.25:10001,
+                128.195.9.26:10001,128.195.9.27:10001,128.195.9.28:10001,128.195.9.29:10001"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+set wait-for-completion-feed "false";
+
+connect feed TweetFeed1 to dataset Tweets1 using policy Br;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/5_2_ingest.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/5_2_ingest.aql
new file mode 100644
index 0000000..65f42cc
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/5_2_ingest.aql
@@ -0,0 +1,26 @@
+use dataverse experiments;
+
+create feed TweetFeed1 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10001,128.195.9.23:10001,128.195.9.24:10001,128.195.9.25:10001,
+                128.195.9.26:10001,128.195.9.27:10001,128.195.9.28:10001,128.195.9.29:10001"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+create feed TweetFeed2 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10002,128.195.9.23:10002,128.195.9.24:10002,128.195.9.25:10002,
+                128.195.9.26:10002,128.195.9.27:10002,128.195.9.28:10002,128.195.9.29:10002"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+set wait-for-completion-feed "false";
+
+connect feed TweetFeed1 to dataset Tweets1 using policy Br;
+connect feed TweetFeed2 to dataset Tweets2 using policy Br;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/5_3_ingest.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/5_3_ingest.aql
new file mode 100644
index 0000000..945332d
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/5_3_ingest.aql
@@ -0,0 +1,37 @@
+use dataverse experiments;
+
+create feed TweetFeed1 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10001,128.195.9.23:10001,128.195.9.24:10001,128.195.9.25:10001,
+                128.195.9.26:10001,128.195.9.27:10001,128.195.9.28:10001,128.195.9.29:10001"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+create feed TweetFeed2 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10002,128.195.9.23:10002,128.195.9.24:10002,128.195.9.25:10002,
+                128.195.9.26:10002,128.195.9.27:10002,128.195.9.28:10002,128.195.9.29:10002"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+create feed TweetFeed3 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10003,128.195.9.23:10003,128.195.9.24:10003,128.195.9.25:10003,
+                128.195.9.26:10003,128.195.9.27:10003,128.195.9.28:10003,128.195.9.29:10003"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+set wait-for-completion-feed "false";
+
+connect feed TweetFeed1 to dataset Tweets1 using policy Br;
+connect feed TweetFeed2 to dataset Tweets2 using policy Br;
+connect feed TweetFeed3 to dataset Tweets3 using policy Br;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/5_4_ingest.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/5_4_ingest.aql
new file mode 100644
index 0000000..a1112b1
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/5_4_ingest.aql
@@ -0,0 +1,48 @@
+use dataverse experiments;
+
+create feed TweetFeed1 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10001,128.195.9.23:10001,128.195.9.24:10001,128.195.9.25:10001,
+                128.195.9.26:10001,128.195.9.27:10001,128.195.9.28:10001,128.195.9.29:10001"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+create feed TweetFeed2 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10002,128.195.9.23:10002,128.195.9.24:10002,128.195.9.25:10002,
+                128.195.9.26:10002,128.195.9.27:10002,128.195.9.28:10002,128.195.9.29:10002"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+create feed TweetFeed3 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10003,128.195.9.23:10003,128.195.9.24:10003,128.195.9.25:10003,
+                128.195.9.26:10003,128.195.9.27:10003,128.195.9.28:10003,128.195.9.29:10003"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+create feed TweetFeed4 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10004,128.195.9.23:10004,128.195.9.24:10004,128.195.9.25:10004,
+                128.195.9.26:10004,128.195.9.27:10004,128.195.9.28:10004,128.195.9.29:10004"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+set wait-for-completion-feed "false";
+
+connect feed TweetFeed1 to dataset Tweets1 using policy Br;
+connect feed TweetFeed2 to dataset Tweets2 using policy Br;
+connect feed TweetFeed3 to dataset Tweets3 using policy Br;
+connect feed TweetFeed4 to dataset Tweets4 using policy Br;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_1_ingest.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_1_ingest.aql
new file mode 100644
index 0000000..8f5654d
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_1_ingest.aql
@@ -0,0 +1,24 @@
+use dataverse experiments;
+
+create feed TweetFeed1 using socket_adapter
+(
+    ("sockets"="127.0.0.1:10001"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+create feed TweetFeed2 using socket_adapter
+(
+    ("sockets"="127.0.0.1:10002"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+set wait-for-completion-feed "false";
+
+connect feed TweetFeed1 to dataset Tweets using policy Br;
+connect feed TweetFeed2 to dataset Tweets using policy Br;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_1_ingest_query.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_1_ingest_query.aql
new file mode 100644
index 0000000..c7614dc
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_1_ingest_query.aql
@@ -0,0 +1,24 @@
+use dataverse experiments;
+
+create feed TweetFeed1 using socket_adapter
+(
+    ("sockets"="127.0.0.1:10001"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+create feed TweetFeed2 using socket_adapter
+(
+    ("sockets"="127.0.0.1:10002"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+set wait-for-completion-feed "false";
+
+connect feed TweetFeed1 to dataset Tweets using policy Brittle;
+connect feed TweetFeed2 to dataset Tweets using policy Brittle;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_2_ingest.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_2_ingest.aql
new file mode 100644
index 0000000..ba4c18e
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_2_ingest.aql
@@ -0,0 +1,24 @@
+use dataverse experiments;
+
+create feed TweetFeed1 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10001,128.195.9.23:10001"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+create feed TweetFeed2 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10002,128.195.9.23:10002"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+set wait-for-completion-feed "false";
+
+connect feed TweetFeed1 to dataset Tweets using policy Br;
+connect feed TweetFeed2 to dataset Tweets using policy Br;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_4_ingest.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_4_ingest.aql
new file mode 100644
index 0000000..c5dd828
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_4_ingest.aql
@@ -0,0 +1,24 @@
+use dataverse experiments;
+
+create feed TweetFeed1 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10001,128.195.9.23:10001,128.195.9.24:10001,128.195.9.25:10001"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+create feed TweetFeed2 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10002,128.195.9.23:10002,128.195.9.24:10002,128.195.9.25:10002"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+set wait-for-completion-feed "false";
+
+connect feed TweetFeed1 to dataset Tweets using policy Br;
+connect feed TweetFeed2 to dataset Tweets using policy Br;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_8_ingest.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_8_ingest.aql
new file mode 100644
index 0000000..6d337bd
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_8_ingest.aql
@@ -0,0 +1,24 @@
+use dataverse experiments;
+
+create feed TweetFeed1 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10001,128.195.9.23:10001,128.195.9.24:10001,128.195.9.25:10001,128.195.9.26:10001,128.195.9.27:10001,128.195.9.28:10001,128.195.9.29:10001"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+create feed TweetFeed2 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10002,128.195.9.23:10002,128.195.9.24:10002,128.195.9.25:10002,128.195.9.26:10002,128.195.9.27:10002,128.195.9.28:10002,128.195.9.29:10002"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+set wait-for-completion-feed "false";
+
+connect feed TweetFeed1 to dataset Tweets using policy Br;
+connect feed TweetFeed2 to dataset Tweets using policy Br;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_8_ingest_query.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_8_ingest_query.aql
new file mode 100644
index 0000000..0d057a2
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_8_ingest_query.aql
@@ -0,0 +1,14 @@
+use dataverse experiments;
+
+create feed TweetFeed1 using socket_adapter
+(
+    ("sockets"="128.195.9.22:10001,128.195.9.23:10001,128.195.9.24:10001,128.195.9.25:10001,128.195.9.26:10001,128.195.9.27:10001,128.195.9.28:10001,128.195.9.29:10001"),
+    ("address-type"="IP"),
+    ("type-name"="TweetMessageType"),
+    ("format"="adm"),
+    ("duration"="1200")
+);
+
+set wait-for-completion-feed "false";
+
+connect feed TweetFeed1 to dataset Tweets using policy Brittle;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_types.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_types.aql
new file mode 100644
index 0000000..6a1168c
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/base/base_types.aql
@@ -0,0 +1,31 @@
+drop dataverse experiments if exists;
+create dataverse experiments;
+use dataverse experiments;
+
+create type TwitterUserType as closed {
+    screen-name: string,
+    lang: string,
+    friends_count: int32,
+    statuses_count: int32,
+    name: string,
+    followers_count: int32
+}
+
+create type TweetMessageType as closed {
+    tweetid: int64,
+    user: TwitterUserType,
+    sender-location: point,
+    send-time: datetime,
+    referred-topics: {{ string }},
+    message-text: string,
+
+    btree-extra-field1: int32,
+    btree-extra-field2: int32,
+    btree-extra-field3: int32,
+    btree-extra-field4: int32,
+    btree-extra-field5: int32,
+    btree-extra-field6: int32,
+    btree-extra-field7: int32,
+    btree-extra-field8: int32,
+    dummy-size-adjuster: string // 357
+}
\ No newline at end of file
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/count.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/count.aql
new file mode 100644
index 0000000..a913831
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/count.aql
@@ -0,0 +1,4 @@
+use dataverse experiments;
+
+let $count := count(for $t in dataset Tweets return $t.tweetid)
+return $count;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_dhbtree.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_dhbtree.aql
new file mode 100644
index 0000000..755e5d7
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_dhbtree.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index dhbtreeLocation on Tweets(sender-location) type dhbtree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_dhvbtree.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_dhvbtree.aql
new file mode 100644
index 0000000..b089c37
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_dhvbtree.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index dhvbtreeLocation on Tweets(sender-location) type dhvbtree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_rtree.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_rtree.aql
new file mode 100644
index 0000000..f46a27a
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_rtree.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index rtreeLocation on Tweets(sender-location) type rtree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_shbtree.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_shbtree.aql
new file mode 100644
index 0000000..d2bbe28
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_shbtree.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index shbtreeLocation on Tweets(sender-location) type shbtree(-180.0, -90.0, 180.0, 90.0);
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_sif.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_sif.aql
new file mode 100644
index 0000000..fce9298
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_1_sif.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create index sifLocation on Tweets(sender-location) type sif(-180.0, -90.0, 180.0, 90.0);
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3.aql
new file mode 100644
index 0000000..78b63c6
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3.aql
@@ -0,0 +1,3 @@
+use dataverse experiments;
+create dataset Tweets(TweetMessageType) primary key tweetid;
+create dataset JoinSeedTweets(TweetMessageType) primary key tweetid;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_dhbtree.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_dhbtree.aql
new file mode 100644
index 0000000..36060d7
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_dhbtree.aql
@@ -0,0 +1,2 @@
+use dataverse experiments;
+create index dhbtreeLocation on Tweets(sender-location) type dhbtree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_dhvbtree.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_dhvbtree.aql
new file mode 100644
index 0000000..2369814
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_dhvbtree.aql
@@ -0,0 +1,2 @@
+use dataverse experiments;
+create index dhvbtreeLocation on Tweets(sender-location) type dhvbtree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_rtree.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_rtree.aql
new file mode 100644
index 0000000..d46cd20
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_rtree.aql
@@ -0,0 +1,2 @@
+use dataverse experiments;
+create index rtreeLocation on Tweets(sender-location) type rtree;
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_shbtree.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_shbtree.aql
new file mode 100644
index 0000000..4f83444
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_shbtree.aql
@@ -0,0 +1,2 @@
+use dataverse experiments;
+create index shbtreeLocation on Tweets(sender-location) type shbtree(-180.0, -90.0, 180.0, 90.0);
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_sif.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_sif.aql
new file mode 100644
index 0000000..7faf699
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_create_sif.aql
@@ -0,0 +1,2 @@
+use dataverse experiments;
+create index sifLocation on Tweets(sender-location) type sif(-180.0, -90.0, 180.0, 90.0);
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_pidx_load.aql b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_pidx_load.aql
new file mode 100644
index 0000000..dce43c5
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/aql/spatial_3_pidx_load.aql
@@ -0,0 +1,26 @@
+use dataverse experiments;
+
+load dataset JoinSeedTweets
+using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"="128.195.9.22:///scratch/youngsk2/spatial-index-experiment/data/QuerySeedTweets10K-from-SyntheticTweets100M-psi27-pid0.adm"),("format"="adm"));
+
+/* for testing */
+/*
+load dataset Tweets 
+using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"="128.195.9.22:///scratch/youngsk2/spatial-index-experiment/data/SyntheticTweets2M-psi27-pid0.adm"),("format"="adm"));
+*/
+
+/* for measurement */
+load dataset Tweets 
+using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"=
+"128.195.9.22:///scratch/youngsk2/spatial-index-experiment/data/SyntheticTweets100M-psi27-pid0.adm, 
+128.195.9.23:///scratch/youngsk2/spatial-index-experiment/data/SyntheticTweets100M-psi26-pid1.adm,
+128.195.9.24:///scratch/youngsk2/spatial-index-experiment/data/SyntheticTweets100M-psi25-pid2.adm,
+128.195.9.25:///scratch/youngsk2/spatial-index-experiment/data/SyntheticTweets100M-psi24-pid3.adm,
+128.195.9.26:///scratch/youngsk2/spatial-index-experiment/data/SyntheticTweets100M-psi23-pid4.adm,
+128.195.9.27:///scratch/youngsk2/spatial-index-experiment/data/SyntheticTweets100M-psi22-pid5.adm,
+128.195.9.28:///scratch/youngsk2/spatial-index-experiment/data/SyntheticTweets100M-psi21-pid6.adm,
+128.195.9.29:///scratch/youngsk2/spatial-index-experiment/data/SyntheticTweets100M-psi20-pid7.adm"),
+("format"="adm"));
\ No newline at end of file
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/balloon.c b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/balloon.c
new file mode 100644
index 0000000..d109be8
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/balloon.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <stdint.h>
+
+  int main() {
+  
+    void *mem;
+    int err;
+    uint64_t size = 4.5 * 1024 * 1024;
+    size *= 1024;
+  
+    mem = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); 
+    printf ("%d\n", mem);
+    err = mlock(mem, size);
+    printf ("err is %d\n", err);
+    while(1) {
+      sleep(10000);
+    }
+    return 0;
+  }
+
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/1node.xml b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/1node.xml
new file mode 100644
index 0000000..39c386f
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/1node.xml
@@ -0,0 +1,39 @@
+<!--
+ ! Copyright 2009-2013 by The Regents of the University of California
+ ! Licensed 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 from
+ !
+ !     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.
+ !-->
+<cluster xmlns="cluster">
+	<name>1node</name>
+    <username>jenkins</username>
+	<working_dir>
+		<dir>/home/jenkins/asterixdb/working</dir>
+		<NFS>true</NFS>
+	</working_dir>
+	<log_dir>/home/jenkins/asterix/logs</log_dir>
+	<txn_log_dir>/home/jenkins/asterix/txnlogs</txn_log_dir>
+	<iodevices>/home/jenkins/asterix</iodevices>
+	<store>storage</store>
+	<java_home>/usr/lib/jvm/jre-1.8.0</java_home>
+	<master_node>
+		<id>master</id>
+		<cluster_ip>127.0.0.1</cluster_ip>
+		<cluster_port>1099</cluster_port>
+		<client_ip>127.0.0.1</client_ip>
+		<client_port>1098</client_port>
+		<http_port>8888</http_port>
+	</master_node>
+	<node>
+		<id>node1</id>
+		<cluster_ip>127.0.0.1</cluster_ip>
+	</node>
+</cluster>
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/2node.xml b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/2node.xml
new file mode 100644
index 0000000..bc027c4
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/2node.xml
@@ -0,0 +1,44 @@
+<!--
+ ! Copyright 2009-2013 by The Regents of the University of California
+ ! Licensed 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 from
+ !
+ !     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.
+ !-->
+<cluster xmlns="cluster">
+	<name>2node</name>
+    <username>youngsk2</username>
+	<working_dir>
+		<dir>/home/youngsk2/asterixdb/working</dir>
+		<NFS>true</NFS>
+	</working_dir>
+	<log_dir>/mnt/data/sde/youngsk2/asterix/logs</log_dir>
+	<txn_log_dir>/lv_scratch/scratch/youngsk2/asterix/txnlogs</txn_log_dir>
+	<iodevices>/mnt/data/sdb/youngsk2/asterix,/mnt/data/sdc/youngsk2/asterix,/mnt/data/sdd/youngsk2/asterix</iodevices>
+	<store>storage</store>
+	<java_home>/home/youngsk2/jdk1.7.0_65</java_home>
+	<master_node>
+		<id>master</id>
+		<cluster_ip>128.195.9.21</cluster_ip>
+		<cluster_port>1099</cluster_port>
+		<client_ip>128.195.9.21</client_ip>
+		<client_port>1098</client_port>
+		<http_port>8888</http_port>
+	</master_node>
+	<node>
+		<id>node1</id>
+		<cluster_ip>128.195.9.22</cluster_ip>
+	</node>
+	<node>
+		<id>node2</id>
+		<cluster_ip>128.195.9.23</cluster_ip>
+	</node>
+</cluster>
+
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/4node.xml b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/4node.xml
new file mode 100644
index 0000000..aabb3f5
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/4node.xml
@@ -0,0 +1,52 @@
+<!--
+ ! Copyright 2009-2013 by The Regents of the University of California
+ ! Licensed 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 from
+ !
+ !     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.
+ !-->
+<cluster xmlns="cluster">
+	<name>4node</name>
+    <username>youngsk2</username>
+	<working_dir>
+		<dir>/home/youngsk2/asterixdb/working</dir>
+		<NFS>true</NFS>
+	</working_dir>
+	<log_dir>/mnt/data/sde/youngsk2/asterix/logs</log_dir>
+	<txn_log_dir>/lv_scratch/scratch/youngsk2/asterix/txnlogs</txn_log_dir>
+	<iodevices>/mnt/data/sdb/youngsk2/asterix,/mnt/data/sdc/youngsk2/asterix,/mnt/data/sdd/youngsk2/asterix</iodevices>
+	<store>storage</store>
+	<java_home>/home/youngsk2/jdk1.7.0_65</java_home>
+	<master_node>
+		<id>master</id>
+		<cluster_ip>128.195.9.21</cluster_ip>
+		<cluster_port>1099</cluster_port>
+		<client_ip>128.195.9.21</client_ip>
+		<client_port>1098</client_port>
+		<http_port>8888</http_port>
+	</master_node>
+	<node>
+		<id>node1</id>
+		<cluster_ip>128.195.9.22</cluster_ip>
+	</node>
+	<node>
+		<id>node2</id>
+		<cluster_ip>128.195.9.23</cluster_ip>
+	</node>
+	<node>
+		<id>node3</id>
+		<cluster_ip>128.195.9.24</cluster_ip>
+	</node>
+	<node>
+		<id>node4</id>
+		<cluster_ip>128.195.9.25</cluster_ip>
+	</node>
+</cluster>
+
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/8node.xml b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/8node.xml
new file mode 100644
index 0000000..1586f5a
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/8node.xml
@@ -0,0 +1,68 @@
+<!--
+ ! Copyright 2009-2013 by The Regents of the University of California
+ ! Licensed 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 from
+ !
+ !     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.
+ !-->
+<cluster xmlns="cluster">
+	<name>8node</name>
+    <username>youngsk2</username>
+	<working_dir>
+		<dir>/home/youngsk2/asterixdb/working</dir>
+		<NFS>true</NFS>
+	</working_dir>
+	<log_dir>/mnt/data/sde/youngsk2/asterix/logs</log_dir>
+	<txn_log_dir>/lv_scratch/scratch/youngsk2/asterix/txnlogs</txn_log_dir>
+	<iodevices>/mnt/data/sdb/youngsk2/asterix,/mnt/data/sdc/youngsk2/asterix,/mnt/data/sdd/youngsk2/asterix</iodevices>
+	<store>storage</store>
+	<java_home>/home/youngsk2/jdk1.7.0_65</java_home>
+	<master_node>
+		<id>master</id>
+		<cluster_ip>128.195.9.21</cluster_ip>
+		<cluster_port>1099</cluster_port>
+		<client_ip>128.195.9.21</client_ip>
+		<client_port>1098</client_port>
+		<http_port>8888</http_port>
+	</master_node>
+	<node>
+		<id>node1</id>
+		<cluster_ip>128.195.9.22</cluster_ip>
+	</node>
+	<node>
+		<id>node2</id>
+		<cluster_ip>128.195.9.23</cluster_ip>
+	</node>
+	<node>
+		<id>node3</id>
+		<cluster_ip>128.195.9.24</cluster_ip>
+	</node>
+	<node>
+		<id>node4</id>
+		<cluster_ip>128.195.9.25</cluster_ip>
+	</node>
+	<node>
+		<id>node5</id>
+		<cluster_ip>128.195.9.26</cluster_ip>
+	</node>
+	<node>
+		<id>node6</id>
+		<cluster_ip>128.195.9.27</cluster_ip>
+	</node>
+	<node>
+		<id>node7</id>
+		<cluster_ip>128.195.9.28</cluster_ip>
+	</node>
+	<node>
+		<id>node8</id>
+		<cluster_ip>128.195.9.29</cluster_ip>
+	</node>
+</cluster>
+
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/asterix-configuration.xml b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/asterix-configuration.xml
new file mode 100644
index 0000000..0159194
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/asterix-configuration.xml
@@ -0,0 +1,259 @@
+<!--
+ ! Copyright 2009-2013 by The Regents of the University of California
+ ! Licensed 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 from
+ !
+ !     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.
+ !-->
+<asterixConfiguration xmlns="asterixconf">
+
+	<property>
+		<name>nc.java.opts</name>
+		<value>-Xms6144m -Xmx7168m</value>
+		<description>JVM parameters for each Node Contoller (NC)</description>
+	</property>
+
+	<property>
+		<name>cc.java.opts</name>
+		<value>-Xms6144m -Xmx6144m</value>
+		<description>JVM parameters for each Cluster Contoller (CC)
+		</description>
+	</property>
+
+    <property>
+        <name>max.wait.active.cluster</name>
+        <value>60</value>
+        <description>Maximum wait (in seconds) for a cluster to be ACTIVE (all nodes are available)
+                before a submitted query/statement can be executed. (Default = 60 seconds)
+        </description>
+    </property>
+
+	<property>
+		<name>storage.buffercache.pagesize</name>
+		<value>131072</value>
+		<description>The page size in bytes for pages in the buffer cache.
+			(Default = "131072" // 128KB)
+		</description>
+	</property>
+
+	<property>
+		<name>storage.buffercache.size</name>
+		<value>3221225472</value>
+		<description>[3GB] The size of memory allocated to the disk buffer cache.
+			The value should be a multiple of the buffer cache page size(Default
+			= "536870912" // 512MB)
+		</description>
+	</property>
+
+	<property>
+		<name>storage.buffercache.maxopenfiles</name>
+		<value>214748364</value>
+		<description>The maximum number of open files in the buffer cache.
+			(Default = "214748364")
+		</description>
+	</property>
+
+    <!-- Buffer size per dataset for in-memory components: 1GB -->
+	<property>
+		<name>storage.memorycomponent.pagesize</name>
+		<value>131072</value>
+		<description>The page size in bytes for pages allocated to memory
+			components. (Default = "131072" // 128KB)
+		</description>
+	</property>
+
+	<property>
+		<name>storage.memorycomponent.numpages</name>
+		<value>8192</value>
+		<description>
+		</description>
+	</property>
+    <!--// Buffer size per dataset for in-memory components -->
+
+	<property>
+		<name>storage.metadata.memorycomponent.numpages</name>
+		<value>64</value>
+		<description>The number of pages to allocate for a memory component.
+			(Default = 64)
+		</description>
+	</property>
+
+    <property>
+		<name>storage.memorycomponent.numcomponents</name>
+		<value>2</value>
+		<description>The number of memory components to be used per lsm index.
+			(Default = 2)
+		</description>
+	</property>
+
+	<property>
+		<name>storage.memorycomponent.globalbudget</name>
+		<value>4399824896</value>
+		<description>[4GB + 8MB]The total size of memory in bytes that the sum of all
+			open memory
+			components cannot exceed. (Default = "536870192" // 512MB)
+		</description>
+	</property>
+
+	<property>
+		<name>storage.lsm.bloomfilter.falsepositiverate</name>
+		<value>0.01</value>
+		<description>The maximum acceptable false positive rate for bloom
+			filters associated with LSM indexes. (Default = "0.01" // 1%)
+		</description>
+	</property>
+
+	<property>
+		<name>txn.log.buffer.numpages</name>
+		<value>2</value>
+		<description>The number of in-memory log buffer pages. (Default = "8")
+		</description>
+	</property>
+
+	<property>
+		<name>txn.log.buffer.pagesize</name>
+		<value>8388608</value>
+		<description>[8MB]The size of pages in the in-memory log buffer. (Default =
+			"524288" // 512KB)
+		</description>
+	</property>
+
+	<property>
+		<name>txn.log.partitionsize</name>
+		<value>2147483648</value>
+		<description>The maximum size of a log file partition allowed before
+			rotating the log to the next partition. (Default = "2147483648" //
+			2GB)
+		</description>
+	</property>
+
+	<property>
+		<name>txn.log.checkpoint.lsnthreshold</name>
+		<value>67108864</value>
+		<description>The size of the window that the maximum LSN is allowed to
+			be ahead of the checkpoint LSN by. (Default = ""67108864" // 64M)
+		</description>
+	</property>
+
+	<property>
+		<name>txn.log.checkpoint.pollfrequency</name>
+		<value>120</value>
+		<description>The time in seconds between that the checkpoint thread
+			waits between polls. (Default = "120" // 120s)
+		</description>
+	</property>
+
+	<property>
+		<name>txn.log.checkpoint.history</name>
+		<value>0</value>
+		<description>The number of old log partition files to keep before
+			discarding. (Default = "0")
+		</description>
+	</property>
+
+	<property>
+		<name>txn.lock.escalationthreshold</name>
+		<value>1000</value>
+		<description>The number of entity level locks that need to be acquired
+			before the locks are coalesced and escalated into a dataset level
+			lock. (Default = "1000")
+		</description>
+	</property>
+
+	<property>
+		<name>txn.lock.shrinktimer</name>
+		<value>5000</value>
+		<description>The time in milliseconds to wait before deallocating
+			unused lock manager memory. (Default = "5000" // 5s)
+		</description>
+	</property>
+
+	<property>
+		<name>txn.lock.timeout.waitthreshold</name>
+		<value>60000</value>
+		<description>The time in milliseconds to wait before labeling a
+			transaction which has been waiting for a lock timed-out. (Default =
+			"60000" // 60s)
+		</description>
+	</property>
+
+	<property>
+		<name>txn.lock.timeout.sweepthreshold</name>
+		<value>10000</value>
+		<description>The time in milliseconds the timeout thread waits between
+			sweeps to detect timed-out transactions. (Default = "10000" // 10s)
+		</description>
+	</property>
+
+	<property>
+		<name>compiler.sortmemory</name>
+		<value>67108864</value>
+		<description>[64MB]The amount of memory in bytes given to sort operations.
+			(Default = "33554432" // 32mb)
+		</description>
+	</property>
+
+	<property>
+		<name>compiler.joinmemory</name>
+		<value>67108864</value>
+		<description>[64MB]The amount of memory in bytes given to join operations.
+			(Default = "33554432" // 32mb)
+		</description>
+	</property>
+
+	<property>
+		<name>compiler.framesize</name>
+		<value>131072</value>
+		<description>The Hyracks frame size that the compiler configures per
+			job. (Default = "131072" // 128KB)
+		</description>
+	</property>
+
+	<property>
+		<name>web.port</name>
+		<value>19001</value>
+		<description>The port for the ASTERIX web interface. (Default = 19001)
+		</description>
+	</property>
+
+	<property>
+		<name>api.port</name>
+		<value>19002</value>
+		<description>The port for the ASTERIX API server. (Default = 19002)
+		</description>
+	</property>
+
+	<property>
+		<name>log.level</name>
+		<value>ALL</value>
+		<description>The minimum log level to be displayed. (Default = INFO)
+		</description>
+	</property>
+	      <property>
+          <name>feed.memory.global.budget</name>
+          <value>1073741824</value>
+          <description>Feed memory budget (1 GB = 1073741824 Bytes)
+          </description>
+      </property>
+  
+      <property>
+          <name>feed.pending.work.threshold</name>
+          <value>1000</value>
+          <description>Feed pending work threshold 
+          </description>
+      </property>
+      
+      <property>
+          <name>feed.max.threshold.period</name>
+          <value>100</value>
+          <description>Feed max threshold period
+          </description>
+      </property>
+</asterixConfiguration>
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/managix-conf.xml b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/managix-conf.xml
new file mode 100644
index 0000000..a21935f
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/configs/managix-conf.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<configuration xmlns="installer">
+    <backup>
+        <hdfs>
+            <version>0.20.2</version>
+            <url></url>
+        </hdfs>
+        <backupDir>/home/youngsk2/managix/clusters/local/working_dir/backup</backupDir>
+    </backup>
+    <zookeeper>
+        <homeDir>/home/youngsk2/managix/.installer/zookeeper_home</homeDir>
+        <clientPort>2900</clientPort>
+        <servers>
+            <java_home>/home/youngsk2/jdk1.7.0_65</java_home>
+            <server>128.195.9.21</server>
+        </servers>
+    </zookeeper>
+</configuration>
\ No newline at end of file
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/1.dgen b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/1.dgen
new file mode 100644
index 0000000..428b3a3
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/1.dgen
@@ -0,0 +1 @@
+127.0.0.1   127.0.0.1:10001
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/2.dgen b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/2.dgen
new file mode 100644
index 0000000..7a51869
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/2.dgen
@@ -0,0 +1,2 @@
+128.195.11.61   128.195.9.22:10001
+128.195.11.62   128.195.9.23:10001
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/4.dgen b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/4.dgen
new file mode 100644
index 0000000..0472cf6
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/4.dgen
@@ -0,0 +1,4 @@
+128.195.11.61   128.195.9.22:10001
+128.195.11.62   128.195.9.23:10001
+128.195.11.63   128.195.9.24:10001
+128.195.11.64   128.195.9.25:10001
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/5_1.dgen b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/5_1.dgen
new file mode 100644
index 0000000..e671eca
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/5_1.dgen
@@ -0,0 +1,8 @@
+128.195.9.30    128.195.9.22:10001
+128.195.9.30    128.195.9.23:10001
+128.195.9.21    128.195.9.24:10001
+128.195.9.21    128.195.9.25:10001
+128.195.11.54   128.195.9.26:10001
+128.195.11.54   128.195.9.27:10001
+128.195.11.55   128.195.9.28:10001
+128.195.11.55   128.195.9.29:10001
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/5_2.dgen b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/5_2.dgen
new file mode 100644
index 0000000..e82412a
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/5_2.dgen
@@ -0,0 +1,16 @@
+128.195.9.30    128.195.9.22:10001
+128.195.9.30    128.195.9.23:10001
+128.195.9.21    128.195.9.24:10001
+128.195.9.21    128.195.9.25:10001
+128.195.11.54   128.195.9.26:10001
+128.195.11.54   128.195.9.27:10001
+128.195.11.55   128.195.9.28:10001
+128.195.11.55   128.195.9.29:10001
+128.195.11.56   128.195.9.22:10002
+128.195.11.56   128.195.9.23:10002
+128.195.11.57   128.195.9.24:10002
+128.195.11.57   128.195.9.25:10002
+128.195.11.59   128.195.9.26:10002
+128.195.11.59   128.195.9.27:10002
+128.195.11.60   128.195.9.28:10002
+128.195.11.60   128.195.9.29:10002
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/5_3.dgen b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/5_3.dgen
new file mode 100644
index 0000000..5846b08
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/5_3.dgen
@@ -0,0 +1,24 @@
+128.195.9.30    128.195.9.22:10001
+128.195.9.30    128.195.9.23:10001
+128.195.9.21    128.195.9.24:10001
+128.195.9.21    128.195.9.25:10001
+128.195.11.54   128.195.9.26:10001
+128.195.11.54   128.195.9.27:10001
+128.195.11.55   128.195.9.28:10001
+128.195.11.55   128.195.9.29:10001
+128.195.11.56   128.195.9.22:10002
+128.195.11.56   128.195.9.23:10002
+128.195.11.57   128.195.9.24:10002
+128.195.11.57   128.195.9.25:10002
+128.195.11.59   128.195.9.26:10002
+128.195.11.59   128.195.9.27:10002
+128.195.11.60   128.195.9.28:10002
+128.195.11.60   128.195.9.29:10002
+128.195.11.62   128.195.9.22:10003
+128.195.11.62   128.195.9.23:10003
+128.195.11.63   128.195.9.24:10003
+128.195.11.63   128.195.9.25:10003
+128.195.11.64   128.195.9.26:10003
+128.195.11.64   128.195.9.27:10003
+128.195.11.65   128.195.9.28:10003
+128.195.11.65   128.195.9.29:10003
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/5_4.dgen b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/5_4.dgen
new file mode 100644
index 0000000..ce6dbb2
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/5_4.dgen
@@ -0,0 +1,32 @@
+128.195.9.30    128.195.9.22:10001
+128.195.9.30    128.195.9.23:10001
+128.195.9.21    128.195.9.24:10001
+128.195.9.21    128.195.9.25:10001
+128.195.11.54   128.195.9.26:10001
+128.195.11.54   128.195.9.27:10001
+128.195.11.55   128.195.9.28:10001
+128.195.11.55   128.195.9.29:10001
+128.195.11.56   128.195.9.22:10002
+128.195.11.56   128.195.9.23:10002
+128.195.11.57   128.195.9.24:10002
+128.195.11.57   128.195.9.25:10002
+128.195.11.59   128.195.9.26:10002
+128.195.11.59   128.195.9.27:10002
+128.195.11.60   128.195.9.28:10002
+128.195.11.60   128.195.9.29:10002
+128.195.11.62   128.195.9.22:10003
+128.195.11.62   128.195.9.23:10003
+128.195.11.63   128.195.9.24:10003
+128.195.11.63   128.195.9.25:10003
+128.195.11.64   128.195.9.26:10003
+128.195.11.64   128.195.9.27:10003
+128.195.11.65   128.195.9.28:10003
+128.195.11.65   128.195.9.29:10003
+128.195.11.66   128.195.9.22:10004
+128.195.11.66   128.195.9.23:10004
+128.195.11.68   128.195.9.24:10004
+128.195.11.68   128.195.9.25:10004
+128.195.11.72   128.195.9.26:10004
+128.195.11.72   128.195.9.27:10004
+128.195.11.86   128.195.9.28:10004
+128.195.11.86   128.195.9.29:10004
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/8.dgen b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/8.dgen
new file mode 100644
index 0000000..8571cbe
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/8.dgen
@@ -0,0 +1,8 @@
+128.195.11.61   128.195.9.22:10001
+128.195.11.62   128.195.9.23:10001
+128.195.11.63   128.195.9.24:10001
+128.195.11.64   128.195.9.25:10001
+128.195.11.65   128.195.9.26:10001
+128.195.11.66   128.195.9.27:10001
+128.195.11.67   128.195.9.28:10001
+128.195.11.68   128.195.9.29:10001
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/8.dqgen b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/8.dqgen
new file mode 100644
index 0000000..8571cbe
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/dgen/8.dqgen
@@ -0,0 +1,8 @@
+128.195.11.61   128.195.9.22:10001
+128.195.11.62   128.195.9.23:10001
+128.195.11.63   128.195.9.24:10001
+128.195.11.64   128.195.9.25:10001
+128.195.11.65   128.195.9.26:10001
+128.195.11.66   128.195.9.27:10001
+128.195.11.67   128.195.9.28:10001
+128.195.11.68   128.195.9.29:10001
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/killdrivers.sh b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/killdrivers.sh
new file mode 100644
index 0000000..9e1e7b0
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/killdrivers.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+jps | grep Driver | awk '{print $1}' | xargs kill -9
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/killscreens.sh b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/killscreens.sh
new file mode 100644
index 0000000..9b6e5f9
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/killscreens.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+screen -ls | grep asterix | cut -d. -f1 | awk '{print $1}' | xargs kill -9
+screen -wipe
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/logging.properties b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/logging.properties
new file mode 100644
index 0000000..e3c448c
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/logging.properties
@@ -0,0 +1,84 @@
+#/*
+# Copyright 2009-2013 by The Regents of the University of California
+# Licensed 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 from
+# 
+#     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.
+#*/
+############################################################
+#  	Default Logging Configuration File
+#
+# You can use a different file by specifying a filename
+# with the java.util.logging.config.file system property.  
+# For example java -Djava.util.logging.config.file=myfile
+############################################################
+
+############################################################
+#  	Global properties
+############################################################
+
+# "handlers" specifies a comma separated list of log Handler 
+# classes.  These handlers will be installed during VM startup.
+# Note that these classes must be on the system classpath.
+# By default we only configure a ConsoleHandler, which will only
+# show messages at the INFO and above levels.
+
+handlers= java.util.logging.ConsoleHandler
+
+# To also add the FileHandler, use the following line instead.
+
+# handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
+
+# Default global logging level.
+# This specifies which kinds of events are logged across
+# all loggers.  For any given facility this global level
+# can be overriden by a facility specific level
+# Note that the ConsoleHandler also has a separate level
+# setting to limit messages printed to the console.
+
+.level= INFO
+# .level= INFO
+# .level= FINE
+# .level = FINEST
+
+############################################################
+# Handler specific properties.
+# Describes specific configuration info for Handlers.
+############################################################
+
+# default file output is in user's home directory.
+
+# java.util.logging.FileHandler.pattern = %h/java%u.log
+# java.util.logging.FileHandler.limit = 50000
+# java.util.logging.FileHandler.count = 1
+# java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
+
+# Limit the message that are printed on the console to FINE and above.
+
+java.util.logging.ConsoleHandler.level = INFO
+java.util.logging.ConsoleHandler.formatter = org.apache.asterix.experiment.logging.ExperimentLogFormatter
+#java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+
+############################################################
+# Facility specific properties.
+# Provides extra control for each logger.
+############################################################
+
+# For example, set the com.xyz.foo logger to only log SEVERE
+# messages:
+
+
+#org.apache.asterix.test.level = INFO
+#org.apache.asterix.level = INFO
+#org.apache.hyracks.algebricks.level = FINE
+#org.apache.hyracks.level = INFO
+#org.apache.asterix.test = INFO
+#org.apache.asterix.installer.test = INFO
diff --git a/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/updateMain.sh b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/updateMain.sh
new file mode 100644
index 0000000..9fc1676
--- /dev/null
+++ b/asterix-experiments/src/main/resources/ingestion-experiment-binary-and-configs/updateMain.sh
@@ -0,0 +1,6 @@
+rm -rf /scratch/youngsk2/spatial-index-experiment/ingestion-experiment-root/ingestion-experiment-binary-and-configs/  
+unzip /home/youngsk2/spatial-index-experiment/ingestion-experiment-binary-and-configs/ingestion-experiment-binary-and-configs.zip -d /scratch/youngsk2/spatial-index-experiment/ingestion-experiment-root/
+unzip /home/youngsk2/spatial-index-experiment/ingestion-experiment-binary-and-configs/asterix-experiments-0.8.7-SNAPSHOT-binary-assembly.zip -d /scratch/youngsk2/spatial-index-experiment/ingestion-experiment-root/ingestion-experiment-binary-and-configs/;  
+rm -rf /scratch/youngsk2/spatial-index-experiment/asterix-instance/* /scratch/youngsk2/spatial-index-experiment/asterix-instance/.installer
+unzip /home/youngsk2/spatial-index-experiment/ingestion-experiment-binary-and-configs/asterix-installer-0.8.7-SNAPSHOT-binary-assembly.zip -d /scratch/youngsk2/spatial-index-experiment/asterix-instance/;
+cp -rf /home/youngsk2/spatial-index-experiment/ingestion-experiment-binary-and-configs/managix-conf.xml /scratch/youngsk2/spatial-index-experiment/asterix-instance/conf/
diff --git a/asterix-external-data/src/main/java/org/apache/asterix/external/util/DataGenerator.java b/asterix-external-data/src/main/java/org/apache/asterix/external/util/DataGenerator.java
index 65099f1..59c9a0f 100644
--- a/asterix-external-data/src/main/java/org/apache/asterix/external/util/DataGenerator.java
+++ b/asterix-external-data/src/main/java/org/apache/asterix/external/util/DataGenerator.java
@@ -106,9 +106,9 @@
         if (usernameSuffix != null) {
             name = name + usernameSuffix;
         }
-        int numFriends = random.nextInt((int) (100)); // draw from Zipfian
+        int numFriends = random.nextInt((100)); // draw from Zipfian
         int statusesCount = random.nextInt(500); // draw from Zipfian
-        int followersCount = random.nextInt((int) (200));
+        int followersCount = random.nextInt((200));
         twUser.reset(screenName, numFriends, statusesCount, name, followersCount);
     }
 
@@ -167,12 +167,16 @@
         public Date getNextRecentDate(Date date) {
             int year = date.getYear()
                     + (date.getYear() == endDate.getYear() ? 0 : random.nextInt(endDate.getYear() - date.getYear()));
-            int month = (year == endDate.getYear()) ? date.getMonth() == endDate.getMonth() ? (endDate.getMonth())
-                    : (date.getMonth() + random.nextInt(endDate.getMonth() - date.getMonth())) : random.nextInt(12) + 1;
+            int month = (year == endDate.getYear())
+                    ? date.getMonth() == endDate.getMonth() ? (endDate.getMonth())
+                            : (date.getMonth() + random.nextInt(endDate.getMonth() - date.getMonth()))
+                    : random.nextInt(12) + 1;
 
-            int day = (year == endDate.getYear()) ? month == endDate.getMonth() ? date.getDay() == endDate.getDay() ? endDate
-                    .getDay() : date.getDay() + random.nextInt(endDate.getDay() - date.getDay())
-                    : random.nextInt(28) + 1
+            int day = (year == endDate.getYear())
+                    ? month == endDate.getMonth()
+                            ? date.getDay() == endDate.getDay() ? endDate.getDay()
+                                    : date.getDay() + random.nextInt(endDate.getDay() - date.getDay())
+                            : random.nextInt(28) + 1
                     : random.nextInt(28) + 1;
             recentDate.reset(month, day, year);
             return recentDate;
@@ -220,6 +224,7 @@
             this.sec = (sec < 10) ? "0" : "" + sec;
         }
 
+        @Override
         public String toString() {
             StringBuilder builder = new StringBuilder();
             builder.append("\"");
@@ -298,6 +303,7 @@
         public Point() {
         }
 
+        @Override
         public String toString() {
             StringBuilder builder = new StringBuilder();
             builder.append("point(\"" + latitude + "," + longitude + "\")");
@@ -665,6 +671,7 @@
             return followersCount;
         }
 
+        @Override
         public String toString() {
             StringBuilder builder = new StringBuilder();
             builder.append("{");
@@ -718,6 +725,7 @@
         public Date() {
         }
 
+        @Override
         public String toString() {
             StringBuilder builder = new StringBuilder();
             builder.append("date");
@@ -773,38 +781,37 @@
             "Busk", "Pheleps", "Teagarden", "Northey", "Baumgartner", "Fleming", "Harris", "Parkinson", "Carpenter",
             "Whirlow", "Bonner", "Wortman", "Rogers", "Scott", "Lowe", "Mckee", "Huston", "Bullard", "Throckmorton",
             "Rummel", "Mathews", "Dull", "Saline", "Tue", "Woolery", "Lalty", "Schrader", "Ramsey", "Eisenmann",
-            "Philbrick", "Sybilla", "Wallace", "Fonblanque", "Paul", "Orbell", "Higgens", "Casteel", "Franks",
-            "Demuth", "Eisenman", "Hay", "Robinson", "Fischer", "Hincken", "Wylie", "Leichter", "Bousum",
-            "Littlefield", "Mcdonald", "Greif", "Rhodes", "Wall", "Steele", "Baldwin", "Smith", "Stewart", "Schere",
-            "Mary", "Aultman", "Emrick", "Guess", "Mitchell", "Painter", "Aft", "Hasely", "Weldi", "Loewentsein",
-            "Poorbaugh", "Kepple", "Noton", "Judge", "Jackson", "Style", "Adcock", "Diller", "Marriman", "Johnston",
-            "Children", "Monahan", "Ehret", "Shaw", "Congdon", "Pinney", "Millard", "Crissman", "Tanner", "Rose",
-            "Knisely", "Cypret", "Sommer", "Poehl", "Hardie", "Bender", "Overholt", "Gottwine", "Beach", "Leslie",
-            "Trevithick", "Langston", "Magor", "Shotts", "Howe", "Hunter", "Cross", "Kistler", "Dealtry", "Christner",
-            "Pennington", "Thorley", "Eckhardstein", "Van", "Stroh", "Stough", "Stall", "Beedell", "Shea", "Garland",
-            "Mays", "Pritchard", "Frankenberger", "Rowley", "Lane", "Baum", "Alliman", "Park", "Jardine", "Butler",
-            "Cherry", "Kooser", "Baxter", "Billimek", "Downing", "Hurst", "Wood", "Baird", "Watkins", "Edwards",
-            "Kemerer", "Harding", "Owens", "Eiford", "Keener", "Garneis", "Fiscina", "Mang", "Draudy", "Mills",
-            "Gibson", "Reese", "Todd", "Ramos", "Levett", "Wilks", "Ward", "Mosser", "Dunlap", "Kifer", "Christopher",
-            "Ashbaugh", "Wynter", "Rawls", "Cribbs", "Haynes", "Thigpen", "Schreckengost", "Bishop", "Linton",
-            "Chapman", "James", "Jerome", "Hook", "Omara", "Houston", "Maclagan", "Sandys", "Pickering", "Blois",
-            "Dickson", "Kemble", "Duncan", "Woodward", "Southern", "Henley", "Treeby", "Cram", "Elsas", "Driggers",
-            "Warrick", "Overstreet", "Hindman", "Buck", "Sulyard", "Wentzel", "Swink", "Butt", "Schaeffer",
-            "Hoffhants", "Bould", "Willcox", "Lotherington", "Bagley", "Graff", "White", "Wheeler", "Sloan",
-            "Rodacker", "Hanford", "Jowers", "Kunkle", "Cass", "Powers", "Gilman", "Mcmichaels", "Hobbs", "Herndon",
-            "Prescott", "Smail", "Mcdonald", "Biery", "Orner", "Richards", "Mueller", "Isaman", "Bruxner", "Goodman",
-            "Barth", "Turzanski", "Vorrasi", "Stainforth", "Nehling", "Rahl", "Erschoff", "Greene", "Mckinnon",
-            "Reade", "Smith", "Pery", "Roose", "Greenwood", "Weisgarber", "Curry", "Holts", "Zadovsky", "Parrish",
-            "Putnam", "Munson", "Mcindoe", "Nickolson", "Brooks", "Bollinger", "Stroble", "Siegrist", "Fulton",
-            "Tomey", "Zoucks", "Roberts", "Otis", "Clarke", "Easter", "Johnson", "Fylbrigg", "Taylor", "Swartzbaugh",
-            "Weinstein", "Gadow", "Sayre", "Marcotte", "Wise", "Atweeke", "Mcfall", "Napier", "Eisenhart", "Canham",
-            "Sealis", "Baughman", "Gertraht", "Losey", "Laurence", "Eva", "Pershing", "Kern", "Pirl", "Rega",
-            "Sanborn", "Kanaga", "Sanders", "Anderson", "Dickinson", "Osteen", "Gettemy", "Crom", "Snyder", "Reed",
-            "Laurenzi", "Riggle", "Tillson", "Fowler", "Raub", "Jenner", "Koepple", "Soames", "Goldvogel", "Dimsdale",
-            "Zimmer", "Giesen", "Baker", "Beail", "Mortland", "Bard", "Sanner", "Knopsnider", "Jenkins", "Bailey",
-            "Werner", "Barrett", "Faust", "Agg", "Tomlinson", "Williams", "Little", "Greenawalt", "Wells", "Wilkins",
-            "Gisiko", "Bauerle", "Harrold", "Prechtl", "Polson", "Faast", "Winton", "Garneys", "Peters", "Potter",
-            "Porter", "Tennant", "Eve", "Dugger", "Jones", "Burch", "Cowper", "Whittier" };
+            "Philbrick", "Sybilla", "Wallace", "Fonblanque", "Paul", "Orbell", "Higgens", "Casteel", "Franks", "Demuth",
+            "Eisenman", "Hay", "Robinson", "Fischer", "Hincken", "Wylie", "Leichter", "Bousum", "Littlefield",
+            "Mcdonald", "Greif", "Rhodes", "Wall", "Steele", "Baldwin", "Smith", "Stewart", "Schere", "Mary", "Aultman",
+            "Emrick", "Guess", "Mitchell", "Painter", "Aft", "Hasely", "Weldi", "Loewentsein", "Poorbaugh", "Kepple",
+            "Noton", "Judge", "Jackson", "Style", "Adcock", "Diller", "Marriman", "Johnston", "Children", "Monahan",
+            "Ehret", "Shaw", "Congdon", "Pinney", "Millard", "Crissman", "Tanner", "Rose", "Knisely", "Cypret",
+            "Sommer", "Poehl", "Hardie", "Bender", "Overholt", "Gottwine", "Beach", "Leslie", "Trevithick", "Langston",
+            "Magor", "Shotts", "Howe", "Hunter", "Cross", "Kistler", "Dealtry", "Christner", "Pennington", "Thorley",
+            "Eckhardstein", "Van", "Stroh", "Stough", "Stall", "Beedell", "Shea", "Garland", "Mays", "Pritchard",
+            "Frankenberger", "Rowley", "Lane", "Baum", "Alliman", "Park", "Jardine", "Butler", "Cherry", "Kooser",
+            "Baxter", "Billimek", "Downing", "Hurst", "Wood", "Baird", "Watkins", "Edwards", "Kemerer", "Harding",
+            "Owens", "Eiford", "Keener", "Garneis", "Fiscina", "Mang", "Draudy", "Mills", "Gibson", "Reese", "Todd",
+            "Ramos", "Levett", "Wilks", "Ward", "Mosser", "Dunlap", "Kifer", "Christopher", "Ashbaugh", "Wynter",
+            "Rawls", "Cribbs", "Haynes", "Thigpen", "Schreckengost", "Bishop", "Linton", "Chapman", "James", "Jerome",
+            "Hook", "Omara", "Houston", "Maclagan", "Sandys", "Pickering", "Blois", "Dickson", "Kemble", "Duncan",
+            "Woodward", "Southern", "Henley", "Treeby", "Cram", "Elsas", "Driggers", "Warrick", "Overstreet", "Hindman",
+            "Buck", "Sulyard", "Wentzel", "Swink", "Butt", "Schaeffer", "Hoffhants", "Bould", "Willcox", "Lotherington",
+            "Bagley", "Graff", "White", "Wheeler", "Sloan", "Rodacker", "Hanford", "Jowers", "Kunkle", "Cass", "Powers",
+            "Gilman", "Mcmichaels", "Hobbs", "Herndon", "Prescott", "Smail", "Mcdonald", "Biery", "Orner", "Richards",
+            "Mueller", "Isaman", "Bruxner", "Goodman", "Barth", "Turzanski", "Vorrasi", "Stainforth", "Nehling", "Rahl",
+            "Erschoff", "Greene", "Mckinnon", "Reade", "Smith", "Pery", "Roose", "Greenwood", "Weisgarber", "Curry",
+            "Holts", "Zadovsky", "Parrish", "Putnam", "Munson", "Mcindoe", "Nickolson", "Brooks", "Bollinger",
+            "Stroble", "Siegrist", "Fulton", "Tomey", "Zoucks", "Roberts", "Otis", "Clarke", "Easter", "Johnson",
+            "Fylbrigg", "Taylor", "Swartzbaugh", "Weinstein", "Gadow", "Sayre", "Marcotte", "Wise", "Atweeke", "Mcfall",
+            "Napier", "Eisenhart", "Canham", "Sealis", "Baughman", "Gertraht", "Losey", "Laurence", "Eva", "Pershing",
+            "Kern", "Pirl", "Rega", "Sanborn", "Kanaga", "Sanders", "Anderson", "Dickinson", "Osteen", "Gettemy",
+            "Crom", "Snyder", "Reed", "Laurenzi", "Riggle", "Tillson", "Fowler", "Raub", "Jenner", "Koepple", "Soames",
+            "Goldvogel", "Dimsdale", "Zimmer", "Giesen", "Baker", "Beail", "Mortland", "Bard", "Sanner", "Knopsnider",
+            "Jenkins", "Bailey", "Werner", "Barrett", "Faust", "Agg", "Tomlinson", "Williams", "Little", "Greenawalt",
+            "Wells", "Wilkins", "Gisiko", "Bauerle", "Harrold", "Prechtl", "Polson", "Faast", "Winton", "Garneys",
+            "Peters", "Potter", "Porter", "Tennant", "Eve", "Dugger", "Jones", "Burch", "Cowper", "Whittier" };
 
     public static String[] firstNames = { "Albert", "Jacquelin", "Dona", "Alia", "Mayme", "Genoveva", "Emma", "Lena",
             "Melody", "Vilma", "Katelyn", "Jeremy", "Coral", "Leann", "Lita", "Gilda", "Kayla", "Alvina", "Maranda",
@@ -825,259 +832,256 @@
             "Cayla", "Elissa", "Claribel", "Sabina", "Mackenzie", "Raina", "Cira", "Mitzie", "Aubrey", "Serafina",
             "Maria", "Katharine", "Esperanza", "Sung", "Daria", "Billye", "Stefanie", "Kasha", "Holly", "Suzanne",
             "Inga", "Flora", "Andria", "Genevie", "Eladia", "Janet", "Erline", "Renna", "Georgeanna", "Delorse",
-            "Elnora", "Rudy", "Rima", "Leanora", "Letisha", "Love", "Alverta", "Pinkie", "Domonique", "Jeannie",
-            "Jose", "Jacqueline", "Tara", "Lily", "Erna", "Tennille", "Galina", "Tamala", "Kirby", "Nichelle",
-            "Myesha", "Farah", "Santa", "Ludie", "Kenia", "Yee", "Micheline", "Maryann", "Elaina", "Ethelyn",
-            "Emmaline", "Shanell", "Marina", "Nila", "Alane", "Shakira", "Dorris", "Belinda", "Elois", "Barbie",
-            "Carita", "Gisela", "Lura", "Fransisca", "Helga", "Peg", "Leonarda", "Earlie", "Deetta", "Jacquetta",
-            "Blossom", "Kayleigh", "Deloras", "Keshia", "Christinia", "Dulce", "Bernie", "Sheba", "Lashanda", "Tula",
-            "Claretta", "Kary", "Jeanette", "Lupita", "Lenora", "Hisako", "Sherise", "Glynda", "Adela", "Chia",
-            "Sudie", "Mindy", "Caroyln", "Lindsey", "Xiomara", "Mercedes", "Onie", "Loan", "Alexis", "Tommie",
-            "Donette", "Monica", "Soo", "Camellia", "Lavera", "Valery", "Ariana", "Sophia", "Loris", "Ginette",
-            "Marielle", "Tari", "Julissa", "Alesia", "Suzanna", "Emelda", "Erin", "Ladawn", "Sherilyn", "Candice",
-            "Nereida", "Fairy", "Carl", "Joel", "Marilee", "Gracia", "Cordie", "So", "Shanita", "Drew", "Cassie",
-            "Sherie", "Marget", "Norma", "Delois", "Debera", "Chanelle", "Catarina", "Aracely", "Carlene", "Tricia",
-            "Aleen", "Katharina", "Marguerita", "Guadalupe", "Margorie", "Mandie", "Kathe", "Chong", "Sage", "Faith",
-            "Maryrose", "Stephany", "Ivy", "Pauline", "Susie", "Cristen", "Jenifer", "Annette", "Debi", "Karmen",
-            "Luci", "Shayla", "Hope", "Ocie", "Sharie", "Tami", "Breana", "Kerry", "Rubye", "Lashay", "Sondra",
-            "Katrice", "Brunilda", "Cortney", "Yan", "Zenobia", "Penni", "Addie", "Lavona", "Noel", "Anika",
-            "Herlinda", "Valencia", "Bunny", "Tory", "Victoria", "Carrie", "Mikaela", "Wilhelmina", "Chung",
-            "Hortencia", "Gerda", "Wen", "Ilana", "Sibyl", "Candida", "Victorina", "Chantell", "Casie", "Emeline",
-            "Dominica", "Cecila", "Delora", "Miesha", "Nova", "Sally", "Ronald", "Charlette", "Francisca", "Mina",
-            "Jenna", "Loraine", "Felisa", "Lulu", "Page", "Lyda", "Babara", "Flor", "Walter", "Chan", "Sherika",
-            "Kala", "Luna", "Vada", "Syreeta", "Slyvia", "Karin", "Renata", "Robbi", "Glenda", "Delsie", "Lizzie",
-            "Genia", "Caitlin", "Bebe", "Cory", "Sam", "Leslee", "Elva", "Caren", "Kasie", "Leticia", "Shannan",
-            "Vickey", "Sandie", "Kyle", "Chang", "Terrilyn", "Sandra", "Elida", "Marketta", "Elsy", "Tu", "Carman",
-            "Ashlie", "Vernia", "Albertine", "Vivian", "Elba", "Bong", "Margy", "Janetta", "Xiao", "Teofila", "Danyel",
-            "Nickole", "Aleisha", "Tera", "Cleotilde", "Dara", "Paulita", "Isela", "Maricela", "Rozella", "Marivel",
-            "Aurora", "Melissa", "Carylon", "Delinda", "Marvella", "Candelaria", "Deidre", "Tawanna", "Myrtie",
-            "Milagro", "Emilie", "Coretta", "Ivette", "Suzann", "Ammie", "Lucina", "Lory", "Tena", "Eleanor",
-            "Cherlyn", "Tiana", "Brianna", "Myra", "Flo", "Carisa", "Kandi", "Erlinda", "Jacqulyn", "Fermina", "Riva",
-            "Palmira", "Lindsay", "Annmarie", "Tamiko", "Carline", "Amelia", "Quiana", "Lashawna", "Veola", "Belva",
-            "Marsha", "Verlene", "Alex", "Leisha", "Camila", "Mirtha", "Melva", "Lina", "Arla", "Cythia", "Towanda",
-            "Aracelis", "Tasia", "Aurore", "Trinity", "Bernadine", "Farrah", "Deneen", "Ines", "Betty", "Lorretta",
-            "Dorethea", "Hertha", "Rochelle", "Juli", "Shenika", "Yung", "Lavon", "Deeanna", "Nakia", "Lynnette",
-            "Dinorah", "Nery", "Elene", "Carolee", "Mira", "Franchesca", "Lavonda", "Leida", "Paulette", "Dorine",
-            "Allegra", "Keva", "Jeffrey", "Bernardina", "Maryln", "Yoko", "Faviola", "Jayne", "Lucilla", "Charita",
-            "Ewa", "Ella", "Maggie", "Ivey", "Bettie", "Jerri", "Marni", "Bibi", "Sabrina", "Sarah", "Marleen",
-            "Katherin", "Remona", "Jamika", "Antonina", "Oliva", "Lajuana", "Fonda", "Sigrid", "Yael", "Billi",
-            "Verona", "Arminda", "Mirna", "Tesha", "Katheleen", "Bonita", "Kamilah", "Patrica", "Julio", "Shaina",
-            "Mellie", "Denyse", "Deandrea", "Alena", "Meg", "Kizzie", "Krissy", "Karly", "Alleen", "Yahaira", "Lucie",
-            "Karena", "Elaine", "Eloise", "Buena", "Marianela", "Renee", "Nan", "Carolynn", "Windy", "Avril", "Jane",
-            "Vida", "Thea", "Marvel", "Rosaline", "Tifany", "Robena", "Azucena", "Carlota", "Mindi", "Andera", "Jenny",
-            "Courtney", "Lyndsey", "Willette", "Kristie", "Shaniqua", "Tabatha", "Ngoc", "Una", "Marlena", "Louetta",
-            "Vernie", "Brandy", "Jacquelyne", "Jenelle", "Elna", "Erminia", "Ida", "Audie", "Louis", "Marisol",
-            "Shawana", "Harriette", "Karol", "Kitty", "Esmeralda", "Vivienne", "Eloisa", "Iris", "Jeanice", "Cammie",
-            "Jacinda", "Shena", "Floy", "Theda", "Lourdes", "Jayna", "Marg", "Kati", "Tanna", "Rosalyn", "Maxima",
-            "Soon", "Angelika", "Shonna", "Merle", "Kassandra", "Deedee", "Heidi", "Marti", "Renae", "Arleen",
-            "Alfredia", "Jewell", "Carley", "Pennie", "Corina", "Tonisha", "Natividad", "Lilliana", "Darcie", "Shawna",
-            "Angel", "Piedad", "Josefa", "Rebbeca", "Natacha", "Nenita", "Petrina", "Carmon", "Chasidy", "Temika",
-            "Dennise", "Renetta", "Augusta", "Shirlee", "Valeri", "Casimira", "Janay", "Berniece", "Deborah", "Yaeko",
-            "Mimi", "Digna", "Irish", "Cher", "Yong", "Lucila", "Jimmie", "Junko", "Lezlie", "Waneta", "Sandee",
-            "Marquita", "Eura", "Freeda", "Annabell", "Laree", "Jaye", "Wendy", "Toshia", "Kylee", "Aleta", "Emiko",
-            "Clorinda", "Sixta", "Audrea", "Juanita", "Birdie", "Reita", "Latanya", "Nia", "Leora", "Laurine",
-            "Krysten", "Jerrie", "Chantel", "Ira", "Sena", "Andre", "Jann", "Marla", "Precious", "Katy", "Gabrielle",
-            "Yvette", "Brook", "Shirlene", "Eldora", "Laura", "Milda", "Euna", "Jettie", "Debora", "Lise", "Edythe",
-            "Leandra", "Shandi", "Araceli", "Johanne", "Nieves", "Denese", "Carmelita", "Nohemi", "Annice", "Natalie",
-            "Yolande", "Jeffie", "Vashti", "Vickie", "Obdulia", "Youlanda", "Lupe", "Tomoko", "Monserrate", "Domitila",
-            "Etsuko", "Adrienne", "Lakesha", "Melissia", "Odessa", "Meagan", "Veronika", "Jolyn", "Isabelle", "Leah",
-            "Rhiannon", "Gianna", "Audra", "Sommer", "Renate", "Perla", "Thao", "Myong", "Lavette", "Mark", "Emilia",
-            "Ariane", "Karl", "Dorie", "Jacquie", "Mia", "Malka", "Shenita", "Tashina", "Christine", "Cherri", "Roni",
-            "Fran", "Mildred", "Sara", "Clarissa", "Fredia", "Elease", "Samuel", "Earlene", "Vernita", "Mae", "Concha",
-            "Renea", "Tamekia", "Hye", "Ingeborg", "Tessa", "Kelly", "Kristin", "Tam", "Sacha", "Kanisha", "Jillian",
-            "Tiffanie", "Ashlee", "Madelyn", "Donya", "Clementine", "Mickie", "My", "Zena", "Terrie", "Samatha",
-            "Gertie", "Tarra", "Natalia", "Sharlene", "Evie", "Shalon", "Rosalee", "Numbers", "Jodi", "Hattie",
-            "Naoma", "Valene", "Whitley", "Claude", "Alline", "Jeanne", "Camie", "Maragret", "Viola", "Kris", "Marlo",
-            "Arcelia", "Shari", "Jalisa", "Corrie", "Eleonor", "Angelyn", "Merry", "Lauren", "Melita", "Gita",
-            "Elenor", "Aurelia", "Janae", "Lyndia", "Margeret", "Shawanda", "Rolande", "Shirl", "Madeleine", "Celinda",
-            "Jaleesa", "Shemika", "Joye", "Tisa", "Trudie", "Kathrine", "Clarita", "Dinah", "Georgia", "Antoinette",
-            "Janis", "Suzette", "Sherri", "Herta", "Arie", "Hedy", "Cassi", "Audrie", "Caryl", "Jazmine", "Jessica",
-            "Beverly", "Elizbeth", "Marylee", "Londa", "Fredericka", "Argelia", "Nana", "Donnette", "Damaris",
-            "Hailey", "Jamee", "Kathlene", "Glayds", "Lydia", "Apryl", "Verla", "Adam", "Concepcion", "Zelda",
-            "Shonta", "Vernice", "Detra", "Meghann", "Sherley", "Sheri", "Kiyoko", "Margarita", "Adaline", "Mariela",
-            "Velda", "Ailene", "Juliane", "Aiko", "Edyth", "Cecelia", "Shavon", "Florance", "Madeline", "Rheba",
-            "Deann", "Ignacia", "Odelia", "Heide", "Mica", "Jennette", "Maricruz", "Ouida", "Darcy", "Laure",
-            "Justina", "Amada", "Laine", "Cruz", "Sunny", "Francene", "Roxanna", "Nam", "Nancie", "Deanna", "Letty",
-            "Britni", "Kazuko", "Lacresha", "Simon", "Caleb", "Milton", "Colton", "Travis", "Miles", "Jonathan",
-            "Logan", "Rolf", "Emilio", "Roberto", "Marcus", "Tim", "Delmar", "Devon", "Kurt", "Edward", "Jeffrey",
-            "Elvis", "Alfonso", "Blair", "Wm", "Sheldon", "Leonel", "Michal", "Federico", "Jacques", "Leslie",
-            "Augustine", "Hugh", "Brant", "Hong", "Sal", "Modesto", "Curtis", "Jefferey", "Adam", "John", "Glenn",
-            "Vance", "Alejandro", "Refugio", "Lucio", "Demarcus", "Chang", "Huey", "Neville", "Preston", "Bert",
-            "Abram", "Foster", "Jamison", "Kirby", "Erich", "Manual", "Dustin", "Derrick", "Donnie", "Jospeh", "Chris",
-            "Josue", "Stevie", "Russ", "Stanley", "Nicolas", "Samuel", "Waldo", "Jake", "Max", "Ernest", "Reinaldo",
-            "Rene", "Gale", "Morris", "Nathan", "Maximo", "Courtney", "Theodore", "Octavio", "Otha", "Delmer",
-            "Graham", "Dean", "Lowell", "Myles", "Colby", "Boyd", "Adolph", "Jarrod", "Nick", "Mark", "Clinton", "Kim",
-            "Sonny", "Dalton", "Tyler", "Jody", "Orville", "Luther", "Rubin", "Hollis", "Rashad", "Barton", "Vicente",
-            "Ted", "Rick", "Carmine", "Clifton", "Gayle", "Christopher", "Jessie", "Bradley", "Clay", "Theo", "Josh",
-            "Mitchell", "Boyce", "Chung", "Eugenio", "August", "Norbert", "Sammie", "Jerry", "Adan", "Edmundo",
-            "Homer", "Hilton", "Tod", "Kirk", "Emmett", "Milan", "Quincy", "Jewell", "Herb", "Steve", "Carmen",
-            "Bobby", "Odis", "Daron", "Jeremy", "Carl", "Hunter", "Tuan", "Thurman", "Asa", "Brenton", "Shane",
-            "Donny", "Andreas", "Teddy", "Dario", "Cyril", "Hoyt", "Teodoro", "Vincenzo", "Hilario", "Daren",
+            "Elnora", "Rudy", "Rima", "Leanora", "Letisha", "Love", "Alverta", "Pinkie", "Domonique", "Jeannie", "Jose",
+            "Jacqueline", "Tara", "Lily", "Erna", "Tennille", "Galina", "Tamala", "Kirby", "Nichelle", "Myesha",
+            "Farah", "Santa", "Ludie", "Kenia", "Yee", "Micheline", "Maryann", "Elaina", "Ethelyn", "Emmaline",
+            "Shanell", "Marina", "Nila", "Alane", "Shakira", "Dorris", "Belinda", "Elois", "Barbie", "Carita", "Gisela",
+            "Lura", "Fransisca", "Helga", "Peg", "Leonarda", "Earlie", "Deetta", "Jacquetta", "Blossom", "Kayleigh",
+            "Deloras", "Keshia", "Christinia", "Dulce", "Bernie", "Sheba", "Lashanda", "Tula", "Claretta", "Kary",
+            "Jeanette", "Lupita", "Lenora", "Hisako", "Sherise", "Glynda", "Adela", "Chia", "Sudie", "Mindy", "Caroyln",
+            "Lindsey", "Xiomara", "Mercedes", "Onie", "Loan", "Alexis", "Tommie", "Donette", "Monica", "Soo",
+            "Camellia", "Lavera", "Valery", "Ariana", "Sophia", "Loris", "Ginette", "Marielle", "Tari", "Julissa",
+            "Alesia", "Suzanna", "Emelda", "Erin", "Ladawn", "Sherilyn", "Candice", "Nereida", "Fairy", "Carl", "Joel",
+            "Marilee", "Gracia", "Cordie", "So", "Shanita", "Drew", "Cassie", "Sherie", "Marget", "Norma", "Delois",
+            "Debera", "Chanelle", "Catarina", "Aracely", "Carlene", "Tricia", "Aleen", "Katharina", "Marguerita",
+            "Guadalupe", "Margorie", "Mandie", "Kathe", "Chong", "Sage", "Faith", "Maryrose", "Stephany", "Ivy",
+            "Pauline", "Susie", "Cristen", "Jenifer", "Annette", "Debi", "Karmen", "Luci", "Shayla", "Hope", "Ocie",
+            "Sharie", "Tami", "Breana", "Kerry", "Rubye", "Lashay", "Sondra", "Katrice", "Brunilda", "Cortney", "Yan",
+            "Zenobia", "Penni", "Addie", "Lavona", "Noel", "Anika", "Herlinda", "Valencia", "Bunny", "Tory", "Victoria",
+            "Carrie", "Mikaela", "Wilhelmina", "Chung", "Hortencia", "Gerda", "Wen", "Ilana", "Sibyl", "Candida",
+            "Victorina", "Chantell", "Casie", "Emeline", "Dominica", "Cecila", "Delora", "Miesha", "Nova", "Sally",
+            "Ronald", "Charlette", "Francisca", "Mina", "Jenna", "Loraine", "Felisa", "Lulu", "Page", "Lyda", "Babara",
+            "Flor", "Walter", "Chan", "Sherika", "Kala", "Luna", "Vada", "Syreeta", "Slyvia", "Karin", "Renata",
+            "Robbi", "Glenda", "Delsie", "Lizzie", "Genia", "Caitlin", "Bebe", "Cory", "Sam", "Leslee", "Elva", "Caren",
+            "Kasie", "Leticia", "Shannan", "Vickey", "Sandie", "Kyle", "Chang", "Terrilyn", "Sandra", "Elida",
+            "Marketta", "Elsy", "Tu", "Carman", "Ashlie", "Vernia", "Albertine", "Vivian", "Elba", "Bong", "Margy",
+            "Janetta", "Xiao", "Teofila", "Danyel", "Nickole", "Aleisha", "Tera", "Cleotilde", "Dara", "Paulita",
+            "Isela", "Maricela", "Rozella", "Marivel", "Aurora", "Melissa", "Carylon", "Delinda", "Marvella",
+            "Candelaria", "Deidre", "Tawanna", "Myrtie", "Milagro", "Emilie", "Coretta", "Ivette", "Suzann", "Ammie",
+            "Lucina", "Lory", "Tena", "Eleanor", "Cherlyn", "Tiana", "Brianna", "Myra", "Flo", "Carisa", "Kandi",
+            "Erlinda", "Jacqulyn", "Fermina", "Riva", "Palmira", "Lindsay", "Annmarie", "Tamiko", "Carline", "Amelia",
+            "Quiana", "Lashawna", "Veola", "Belva", "Marsha", "Verlene", "Alex", "Leisha", "Camila", "Mirtha", "Melva",
+            "Lina", "Arla", "Cythia", "Towanda", "Aracelis", "Tasia", "Aurore", "Trinity", "Bernadine", "Farrah",
+            "Deneen", "Ines", "Betty", "Lorretta", "Dorethea", "Hertha", "Rochelle", "Juli", "Shenika", "Yung", "Lavon",
+            "Deeanna", "Nakia", "Lynnette", "Dinorah", "Nery", "Elene", "Carolee", "Mira", "Franchesca", "Lavonda",
+            "Leida", "Paulette", "Dorine", "Allegra", "Keva", "Jeffrey", "Bernardina", "Maryln", "Yoko", "Faviola",
+            "Jayne", "Lucilla", "Charita", "Ewa", "Ella", "Maggie", "Ivey", "Bettie", "Jerri", "Marni", "Bibi",
+            "Sabrina", "Sarah", "Marleen", "Katherin", "Remona", "Jamika", "Antonina", "Oliva", "Lajuana", "Fonda",
+            "Sigrid", "Yael", "Billi", "Verona", "Arminda", "Mirna", "Tesha", "Katheleen", "Bonita", "Kamilah",
+            "Patrica", "Julio", "Shaina", "Mellie", "Denyse", "Deandrea", "Alena", "Meg", "Kizzie", "Krissy", "Karly",
+            "Alleen", "Yahaira", "Lucie", "Karena", "Elaine", "Eloise", "Buena", "Marianela", "Renee", "Nan",
+            "Carolynn", "Windy", "Avril", "Jane", "Vida", "Thea", "Marvel", "Rosaline", "Tifany", "Robena", "Azucena",
+            "Carlota", "Mindi", "Andera", "Jenny", "Courtney", "Lyndsey", "Willette", "Kristie", "Shaniqua", "Tabatha",
+            "Ngoc", "Una", "Marlena", "Louetta", "Vernie", "Brandy", "Jacquelyne", "Jenelle", "Elna", "Erminia", "Ida",
+            "Audie", "Louis", "Marisol", "Shawana", "Harriette", "Karol", "Kitty", "Esmeralda", "Vivienne", "Eloisa",
+            "Iris", "Jeanice", "Cammie", "Jacinda", "Shena", "Floy", "Theda", "Lourdes", "Jayna", "Marg", "Kati",
+            "Tanna", "Rosalyn", "Maxima", "Soon", "Angelika", "Shonna", "Merle", "Kassandra", "Deedee", "Heidi",
+            "Marti", "Renae", "Arleen", "Alfredia", "Jewell", "Carley", "Pennie", "Corina", "Tonisha", "Natividad",
+            "Lilliana", "Darcie", "Shawna", "Angel", "Piedad", "Josefa", "Rebbeca", "Natacha", "Nenita", "Petrina",
+            "Carmon", "Chasidy", "Temika", "Dennise", "Renetta", "Augusta", "Shirlee", "Valeri", "Casimira", "Janay",
+            "Berniece", "Deborah", "Yaeko", "Mimi", "Digna", "Irish", "Cher", "Yong", "Lucila", "Jimmie", "Junko",
+            "Lezlie", "Waneta", "Sandee", "Marquita", "Eura", "Freeda", "Annabell", "Laree", "Jaye", "Wendy", "Toshia",
+            "Kylee", "Aleta", "Emiko", "Clorinda", "Sixta", "Audrea", "Juanita", "Birdie", "Reita", "Latanya", "Nia",
+            "Leora", "Laurine", "Krysten", "Jerrie", "Chantel", "Ira", "Sena", "Andre", "Jann", "Marla", "Precious",
+            "Katy", "Gabrielle", "Yvette", "Brook", "Shirlene", "Eldora", "Laura", "Milda", "Euna", "Jettie", "Debora",
+            "Lise", "Edythe", "Leandra", "Shandi", "Araceli", "Johanne", "Nieves", "Denese", "Carmelita", "Nohemi",
+            "Annice", "Natalie", "Yolande", "Jeffie", "Vashti", "Vickie", "Obdulia", "Youlanda", "Lupe", "Tomoko",
+            "Monserrate", "Domitila", "Etsuko", "Adrienne", "Lakesha", "Melissia", "Odessa", "Meagan", "Veronika",
+            "Jolyn", "Isabelle", "Leah", "Rhiannon", "Gianna", "Audra", "Sommer", "Renate", "Perla", "Thao", "Myong",
+            "Lavette", "Mark", "Emilia", "Ariane", "Karl", "Dorie", "Jacquie", "Mia", "Malka", "Shenita", "Tashina",
+            "Christine", "Cherri", "Roni", "Fran", "Mildred", "Sara", "Clarissa", "Fredia", "Elease", "Samuel",
+            "Earlene", "Vernita", "Mae", "Concha", "Renea", "Tamekia", "Hye", "Ingeborg", "Tessa", "Kelly", "Kristin",
+            "Tam", "Sacha", "Kanisha", "Jillian", "Tiffanie", "Ashlee", "Madelyn", "Donya", "Clementine", "Mickie",
+            "My", "Zena", "Terrie", "Samatha", "Gertie", "Tarra", "Natalia", "Sharlene", "Evie", "Shalon", "Rosalee",
+            "Numbers", "Jodi", "Hattie", "Naoma", "Valene", "Whitley", "Claude", "Alline", "Jeanne", "Camie",
+            "Maragret", "Viola", "Kris", "Marlo", "Arcelia", "Shari", "Jalisa", "Corrie", "Eleonor", "Angelyn", "Merry",
+            "Lauren", "Melita", "Gita", "Elenor", "Aurelia", "Janae", "Lyndia", "Margeret", "Shawanda", "Rolande",
+            "Shirl", "Madeleine", "Celinda", "Jaleesa", "Shemika", "Joye", "Tisa", "Trudie", "Kathrine", "Clarita",
+            "Dinah", "Georgia", "Antoinette", "Janis", "Suzette", "Sherri", "Herta", "Arie", "Hedy", "Cassi", "Audrie",
+            "Caryl", "Jazmine", "Jessica", "Beverly", "Elizbeth", "Marylee", "Londa", "Fredericka", "Argelia", "Nana",
+            "Donnette", "Damaris", "Hailey", "Jamee", "Kathlene", "Glayds", "Lydia", "Apryl", "Verla", "Adam",
+            "Concepcion", "Zelda", "Shonta", "Vernice", "Detra", "Meghann", "Sherley", "Sheri", "Kiyoko", "Margarita",
+            "Adaline", "Mariela", "Velda", "Ailene", "Juliane", "Aiko", "Edyth", "Cecelia", "Shavon", "Florance",
+            "Madeline", "Rheba", "Deann", "Ignacia", "Odelia", "Heide", "Mica", "Jennette", "Maricruz", "Ouida",
+            "Darcy", "Laure", "Justina", "Amada", "Laine", "Cruz", "Sunny", "Francene", "Roxanna", "Nam", "Nancie",
+            "Deanna", "Letty", "Britni", "Kazuko", "Lacresha", "Simon", "Caleb", "Milton", "Colton", "Travis", "Miles",
+            "Jonathan", "Logan", "Rolf", "Emilio", "Roberto", "Marcus", "Tim", "Delmar", "Devon", "Kurt", "Edward",
+            "Jeffrey", "Elvis", "Alfonso", "Blair", "Wm", "Sheldon", "Leonel", "Michal", "Federico", "Jacques",
+            "Leslie", "Augustine", "Hugh", "Brant", "Hong", "Sal", "Modesto", "Curtis", "Jefferey", "Adam", "John",
+            "Glenn", "Vance", "Alejandro", "Refugio", "Lucio", "Demarcus", "Chang", "Huey", "Neville", "Preston",
+            "Bert", "Abram", "Foster", "Jamison", "Kirby", "Erich", "Manual", "Dustin", "Derrick", "Donnie", "Jospeh",
+            "Chris", "Josue", "Stevie", "Russ", "Stanley", "Nicolas", "Samuel", "Waldo", "Jake", "Max", "Ernest",
+            "Reinaldo", "Rene", "Gale", "Morris", "Nathan", "Maximo", "Courtney", "Theodore", "Octavio", "Otha",
+            "Delmer", "Graham", "Dean", "Lowell", "Myles", "Colby", "Boyd", "Adolph", "Jarrod", "Nick", "Mark",
+            "Clinton", "Kim", "Sonny", "Dalton", "Tyler", "Jody", "Orville", "Luther", "Rubin", "Hollis", "Rashad",
+            "Barton", "Vicente", "Ted", "Rick", "Carmine", "Clifton", "Gayle", "Christopher", "Jessie", "Bradley",
+            "Clay", "Theo", "Josh", "Mitchell", "Boyce", "Chung", "Eugenio", "August", "Norbert", "Sammie", "Jerry",
+            "Adan", "Edmundo", "Homer", "Hilton", "Tod", "Kirk", "Emmett", "Milan", "Quincy", "Jewell", "Herb", "Steve",
+            "Carmen", "Bobby", "Odis", "Daron", "Jeremy", "Carl", "Hunter", "Tuan", "Thurman", "Asa", "Brenton",
+            "Shane", "Donny", "Andreas", "Teddy", "Dario", "Cyril", "Hoyt", "Teodoro", "Vincenzo", "Hilario", "Daren",
             "Agustin", "Marquis", "Ezekiel", "Brendan", "Johnson", "Alden", "Richie", "Granville", "Chad", "Joseph",
             "Lamont", "Jordon", "Gilberto", "Chong", "Rosendo", "Eddy", "Rob", "Dewitt", "Andre", "Titus", "Russell",
             "Rigoberto", "Dick", "Garland", "Gabriel", "Hank", "Darius", "Ignacio", "Lazaro", "Johnie", "Mauro",
             "Edmund", "Trent", "Harris", "Osvaldo", "Marvin", "Judson", "Rodney", "Randall", "Renato", "Richard",
             "Denny", "Jon", "Doyle", "Cristopher", "Wilson", "Christian", "Jamie", "Roland", "Ken", "Tad", "Romeo",
             "Seth", "Quinton", "Byron", "Ruben", "Darrel", "Deandre", "Broderick", "Harold", "Ty", "Monroe", "Landon",
-            "Mohammed", "Angel", "Arlen", "Elias", "Andres", "Carlton", "Numbers", "Tony", "Thaddeus", "Issac",
-            "Elmer", "Antoine", "Ned", "Fermin", "Grover", "Benito", "Abdul", "Cortez", "Eric", "Maxwell", "Coy",
-            "Gavin", "Rich", "Andy", "Del", "Giovanni", "Major", "Efren", "Horacio", "Joaquin", "Charles", "Noah",
-            "Deon", "Pasquale", "Reed", "Fausto", "Jermaine", "Irvin", "Ray", "Tobias", "Carter", "Yong", "Jorge",
-            "Brent", "Daniel", "Zane", "Walker", "Thad", "Shaun", "Jaime", "Mckinley", "Bradford", "Nathanial",
-            "Jerald", "Aubrey", "Virgil", "Abel", "Philip", "Chester", "Chadwick", "Dominick", "Britt", "Emmitt",
-            "Ferdinand", "Julian", "Reid", "Santos", "Dwain", "Morgan", "James", "Marion", "Micheal", "Eddie", "Brett",
-            "Stacy", "Kerry", "Dale", "Nicholas", "Darrick", "Freeman", "Scott", "Newton", "Sherman", "Felton",
-            "Cedrick", "Winfred", "Brad", "Fredric", "Dewayne", "Virgilio", "Reggie", "Edgar", "Heriberto", "Shad",
-            "Timmy", "Javier", "Nestor", "Royal", "Lynn", "Irwin", "Ismael", "Jonas", "Wiley", "Austin", "Kieth",
-            "Gonzalo", "Paris", "Earnest", "Arron", "Jarred", "Todd", "Erik", "Maria", "Chauncey", "Neil", "Conrad",
-            "Maurice", "Roosevelt", "Jacob", "Sydney", "Lee", "Basil", "Louis", "Rodolfo", "Rodger", "Roman", "Corey",
-            "Ambrose", "Cristobal", "Sylvester", "Benton", "Franklin", "Marcelo", "Guillermo", "Toby", "Jeramy",
-            "Donn", "Danny", "Dwight", "Clifford", "Valentine", "Matt", "Jules", "Kareem", "Ronny", "Lonny", "Son",
-            "Leopoldo", "Dannie", "Gregg", "Dillon", "Orlando", "Weston", "Kermit", "Damian", "Abraham", "Walton",
-            "Adrian", "Rudolf", "Will", "Les", "Norberto", "Fred", "Tyrone", "Ariel", "Terry", "Emmanuel", "Anderson",
-            "Elton", "Otis", "Derek", "Frankie", "Gino", "Lavern", "Jarod", "Kenny", "Dane", "Keenan", "Bryant",
-            "Eusebio", "Dorian", "Ali", "Lucas", "Wilford", "Jeremiah", "Warner", "Woodrow", "Galen", "Bob",
-            "Johnathon", "Amado", "Michel", "Harry", "Zachery", "Taylor", "Booker", "Hershel", "Mohammad", "Darrell",
-            "Kyle", "Stuart", "Marlin", "Hyman", "Jeffery", "Sidney", "Merrill", "Roy", "Garrett", "Porter", "Kenton",
-            "Giuseppe", "Terrance", "Trey", "Felix", "Buster", "Von", "Jackie", "Linwood", "Darron", "Francisco",
-            "Bernie", "Diego", "Brendon", "Cody", "Marco", "Ahmed", "Antonio", "Vince", "Brooks", "Kendrick", "Ross",
-            "Mohamed", "Jim", "Benny", "Gerald", "Pablo", "Charlie", "Antony", "Werner", "Hipolito", "Minh", "Mel",
-            "Derick", "Armand", "Fidel", "Lewis", "Donnell", "Desmond", "Vaughn", "Guadalupe", "Keneth", "Rodrick",
-            "Spencer", "Chas", "Gus", "Harlan", "Wes", "Carmelo", "Jefferson", "Gerard", "Jarvis", "Haywood", "Hayden",
-            "Sergio", "Gene", "Edgardo", "Colin", "Horace", "Dominic", "Aldo", "Adolfo", "Juan", "Man", "Lenard",
-            "Clement", "Everett", "Hal", "Bryon", "Mason", "Emerson", "Earle", "Laurence", "Columbus", "Lamar",
-            "Douglas", "Ian", "Fredrick", "Marc", "Loren", "Wallace", "Randell", "Noble", "Ricardo", "Rory", "Lindsey",
-            "Boris", "Bill", "Carlos", "Domingo", "Grant", "Craig", "Ezra", "Matthew", "Van", "Rudy", "Danial",
-            "Brock", "Maynard", "Vincent", "Cole", "Damion", "Ellsworth", "Marcel", "Markus", "Rueben", "Tanner",
-            "Reyes", "Hung", "Kennith", "Lindsay", "Howard", "Ralph", "Jed", "Monte", "Garfield", "Avery", "Bernardo",
-            "Malcolm", "Sterling", "Ezequiel", "Kristofer", "Luciano", "Casey", "Rosario", "Ellis", "Quintin",
-            "Trevor", "Miquel", "Jordan", "Arthur", "Carson", "Tyron", "Grady", "Walter", "Jonathon", "Ricky",
-            "Bennie", "Terrence", "Dion", "Dusty", "Roderick", "Isaac", "Rodrigo", "Harrison", "Zack", "Dee", "Devin",
-            "Rey", "Ulysses", "Clint", "Greg", "Dino", "Frances", "Wade", "Franklyn", "Jude", "Bradly", "Salvador",
-            "Rocky", "Weldon", "Lloyd", "Milford", "Clarence", "Alec", "Allan", "Bobbie", "Oswaldo", "Wilfred",
-            "Raleigh", "Shelby", "Willy", "Alphonso", "Arnoldo", "Robbie", "Truman", "Nicky", "Quinn", "Damien",
-            "Lacy", "Marcos", "Parker", "Burt", "Carroll", "Denver", "Buck", "Dong", "Normand", "Billie", "Edwin",
-            "Troy", "Arden", "Rusty", "Tommy", "Kenneth", "Leo", "Claud", "Joel", "Kendall", "Dante", "Milo", "Cruz",
-            "Lucien", "Ramon", "Jarrett", "Scottie", "Deshawn", "Ronnie", "Pete", "Alonzo", "Whitney", "Stefan",
-            "Sebastian", "Edmond", "Enrique", "Branden", "Leonard", "Loyd", "Olin", "Ron", "Rhett", "Frederic",
-            "Orval", "Tyrell", "Gail", "Eli", "Antonia", "Malcom", "Sandy", "Stacey", "Nickolas", "Hosea", "Santo",
-            "Oscar", "Fletcher", "Dave", "Patrick", "Dewey", "Bo", "Vito", "Blaine", "Randy", "Robin", "Winston",
-            "Sammy", "Edwardo", "Manuel", "Valentin", "Stanford", "Filiberto", "Buddy", "Zachariah", "Johnnie",
-            "Elbert", "Paul", "Isreal", "Jerrold", "Leif", "Owen", "Sung", "Junior", "Raphael", "Josef", "Donte",
-            "Allen", "Florencio", "Raymond", "Lauren", "Collin", "Eliseo", "Bruno", "Martin", "Lyndon", "Kurtis",
-            "Salvatore", "Erwin", "Michael", "Sean", "Davis", "Alberto", "King", "Rolland", "Joe", "Tory", "Chase",
-            "Dallas", "Vernon", "Beau", "Terrell", "Reynaldo", "Monty", "Jame", "Dirk", "Florentino", "Reuben", "Saul",
-            "Emory", "Esteban", "Michale", "Claudio", "Jacinto", "Kelley", "Levi", "Andrea", "Lanny", "Wendell",
-            "Elwood", "Joan", "Felipe", "Palmer", "Elmo", "Lawrence", "Hubert", "Rudolph", "Duane", "Cordell",
-            "Everette", "Mack", "Alan", "Efrain", "Trenton", "Bryan", "Tom", "Wilmer", "Clyde", "Chance", "Lou",
-            "Brain", "Justin", "Phil", "Jerrod", "George", "Kris", "Cyrus", "Emery", "Rickey", "Lincoln", "Renaldo",
-            "Mathew", "Luke", "Dwayne", "Alexis", "Jackson", "Gil", "Marty", "Burton", "Emil", "Glen", "Willian",
-            "Clemente", "Keven", "Barney", "Odell", "Reginald", "Aurelio", "Damon", "Ward", "Gustavo", "Harley",
-            "Peter", "Anibal", "Arlie", "Nigel", "Oren", "Zachary", "Scot", "Bud", "Wilbert", "Bart", "Josiah",
-            "Marlon", "Eldon", "Darryl", "Roger", "Anthony", "Omer", "Francis", "Patricia", "Moises", "Chuck",
-            "Waylon", "Hector", "Jamaal", "Cesar", "Julius", "Rex", "Norris", "Ollie", "Isaias", "Quentin", "Graig",
-            "Lyle", "Jeffry", "Karl", "Lester", "Danilo", "Mike", "Dylan", "Carlo", "Ryan", "Leon", "Percy", "Lucius",
-            "Jamel", "Lesley", "Joey", "Cornelius", "Rico", "Arnulfo", "Chet", "Margarito", "Ernie", "Nathanael",
-            "Amos", "Cleveland", "Luigi", "Alfonzo", "Phillip", "Clair", "Elroy", "Alva", "Hans", "Shon", "Gary",
-            "Jesus", "Cary", "Silas", "Keith", "Israel", "Willard", "Randolph", "Dan", "Adalberto", "Claude",
+            "Mohammed", "Angel", "Arlen", "Elias", "Andres", "Carlton", "Numbers", "Tony", "Thaddeus", "Issac", "Elmer",
+            "Antoine", "Ned", "Fermin", "Grover", "Benito", "Abdul", "Cortez", "Eric", "Maxwell", "Coy", "Gavin",
+            "Rich", "Andy", "Del", "Giovanni", "Major", "Efren", "Horacio", "Joaquin", "Charles", "Noah", "Deon",
+            "Pasquale", "Reed", "Fausto", "Jermaine", "Irvin", "Ray", "Tobias", "Carter", "Yong", "Jorge", "Brent",
+            "Daniel", "Zane", "Walker", "Thad", "Shaun", "Jaime", "Mckinley", "Bradford", "Nathanial", "Jerald",
+            "Aubrey", "Virgil", "Abel", "Philip", "Chester", "Chadwick", "Dominick", "Britt", "Emmitt", "Ferdinand",
+            "Julian", "Reid", "Santos", "Dwain", "Morgan", "James", "Marion", "Micheal", "Eddie", "Brett", "Stacy",
+            "Kerry", "Dale", "Nicholas", "Darrick", "Freeman", "Scott", "Newton", "Sherman", "Felton", "Cedrick",
+            "Winfred", "Brad", "Fredric", "Dewayne", "Virgilio", "Reggie", "Edgar", "Heriberto", "Shad", "Timmy",
+            "Javier", "Nestor", "Royal", "Lynn", "Irwin", "Ismael", "Jonas", "Wiley", "Austin", "Kieth", "Gonzalo",
+            "Paris", "Earnest", "Arron", "Jarred", "Todd", "Erik", "Maria", "Chauncey", "Neil", "Conrad", "Maurice",
+            "Roosevelt", "Jacob", "Sydney", "Lee", "Basil", "Louis", "Rodolfo", "Rodger", "Roman", "Corey", "Ambrose",
+            "Cristobal", "Sylvester", "Benton", "Franklin", "Marcelo", "Guillermo", "Toby", "Jeramy", "Donn", "Danny",
+            "Dwight", "Clifford", "Valentine", "Matt", "Jules", "Kareem", "Ronny", "Lonny", "Son", "Leopoldo", "Dannie",
+            "Gregg", "Dillon", "Orlando", "Weston", "Kermit", "Damian", "Abraham", "Walton", "Adrian", "Rudolf", "Will",
+            "Les", "Norberto", "Fred", "Tyrone", "Ariel", "Terry", "Emmanuel", "Anderson", "Elton", "Otis", "Derek",
+            "Frankie", "Gino", "Lavern", "Jarod", "Kenny", "Dane", "Keenan", "Bryant", "Eusebio", "Dorian", "Ali",
+            "Lucas", "Wilford", "Jeremiah", "Warner", "Woodrow", "Galen", "Bob", "Johnathon", "Amado", "Michel",
+            "Harry", "Zachery", "Taylor", "Booker", "Hershel", "Mohammad", "Darrell", "Kyle", "Stuart", "Marlin",
+            "Hyman", "Jeffery", "Sidney", "Merrill", "Roy", "Garrett", "Porter", "Kenton", "Giuseppe", "Terrance",
+            "Trey", "Felix", "Buster", "Von", "Jackie", "Linwood", "Darron", "Francisco", "Bernie", "Diego", "Brendon",
+            "Cody", "Marco", "Ahmed", "Antonio", "Vince", "Brooks", "Kendrick", "Ross", "Mohamed", "Jim", "Benny",
+            "Gerald", "Pablo", "Charlie", "Antony", "Werner", "Hipolito", "Minh", "Mel", "Derick", "Armand", "Fidel",
+            "Lewis", "Donnell", "Desmond", "Vaughn", "Guadalupe", "Keneth", "Rodrick", "Spencer", "Chas", "Gus",
+            "Harlan", "Wes", "Carmelo", "Jefferson", "Gerard", "Jarvis", "Haywood", "Hayden", "Sergio", "Gene",
+            "Edgardo", "Colin", "Horace", "Dominic", "Aldo", "Adolfo", "Juan", "Man", "Lenard", "Clement", "Everett",
+            "Hal", "Bryon", "Mason", "Emerson", "Earle", "Laurence", "Columbus", "Lamar", "Douglas", "Ian", "Fredrick",
+            "Marc", "Loren", "Wallace", "Randell", "Noble", "Ricardo", "Rory", "Lindsey", "Boris", "Bill", "Carlos",
+            "Domingo", "Grant", "Craig", "Ezra", "Matthew", "Van", "Rudy", "Danial", "Brock", "Maynard", "Vincent",
+            "Cole", "Damion", "Ellsworth", "Marcel", "Markus", "Rueben", "Tanner", "Reyes", "Hung", "Kennith",
+            "Lindsay", "Howard", "Ralph", "Jed", "Monte", "Garfield", "Avery", "Bernardo", "Malcolm", "Sterling",
+            "Ezequiel", "Kristofer", "Luciano", "Casey", "Rosario", "Ellis", "Quintin", "Trevor", "Miquel", "Jordan",
+            "Arthur", "Carson", "Tyron", "Grady", "Walter", "Jonathon", "Ricky", "Bennie", "Terrence", "Dion", "Dusty",
+            "Roderick", "Isaac", "Rodrigo", "Harrison", "Zack", "Dee", "Devin", "Rey", "Ulysses", "Clint", "Greg",
+            "Dino", "Frances", "Wade", "Franklyn", "Jude", "Bradly", "Salvador", "Rocky", "Weldon", "Lloyd", "Milford",
+            "Clarence", "Alec", "Allan", "Bobbie", "Oswaldo", "Wilfred", "Raleigh", "Shelby", "Willy", "Alphonso",
+            "Arnoldo", "Robbie", "Truman", "Nicky", "Quinn", "Damien", "Lacy", "Marcos", "Parker", "Burt", "Carroll",
+            "Denver", "Buck", "Dong", "Normand", "Billie", "Edwin", "Troy", "Arden", "Rusty", "Tommy", "Kenneth", "Leo",
+            "Claud", "Joel", "Kendall", "Dante", "Milo", "Cruz", "Lucien", "Ramon", "Jarrett", "Scottie", "Deshawn",
+            "Ronnie", "Pete", "Alonzo", "Whitney", "Stefan", "Sebastian", "Edmond", "Enrique", "Branden", "Leonard",
+            "Loyd", "Olin", "Ron", "Rhett", "Frederic", "Orval", "Tyrell", "Gail", "Eli", "Antonia", "Malcom", "Sandy",
+            "Stacey", "Nickolas", "Hosea", "Santo", "Oscar", "Fletcher", "Dave", "Patrick", "Dewey", "Bo", "Vito",
+            "Blaine", "Randy", "Robin", "Winston", "Sammy", "Edwardo", "Manuel", "Valentin", "Stanford", "Filiberto",
+            "Buddy", "Zachariah", "Johnnie", "Elbert", "Paul", "Isreal", "Jerrold", "Leif", "Owen", "Sung", "Junior",
+            "Raphael", "Josef", "Donte", "Allen", "Florencio", "Raymond", "Lauren", "Collin", "Eliseo", "Bruno",
+            "Martin", "Lyndon", "Kurtis", "Salvatore", "Erwin", "Michael", "Sean", "Davis", "Alberto", "King",
+            "Rolland", "Joe", "Tory", "Chase", "Dallas", "Vernon", "Beau", "Terrell", "Reynaldo", "Monty", "Jame",
+            "Dirk", "Florentino", "Reuben", "Saul", "Emory", "Esteban", "Michale", "Claudio", "Jacinto", "Kelley",
+            "Levi", "Andrea", "Lanny", "Wendell", "Elwood", "Joan", "Felipe", "Palmer", "Elmo", "Lawrence", "Hubert",
+            "Rudolph", "Duane", "Cordell", "Everette", "Mack", "Alan", "Efrain", "Trenton", "Bryan", "Tom", "Wilmer",
+            "Clyde", "Chance", "Lou", "Brain", "Justin", "Phil", "Jerrod", "George", "Kris", "Cyrus", "Emery", "Rickey",
+            "Lincoln", "Renaldo", "Mathew", "Luke", "Dwayne", "Alexis", "Jackson", "Gil", "Marty", "Burton", "Emil",
+            "Glen", "Willian", "Clemente", "Keven", "Barney", "Odell", "Reginald", "Aurelio", "Damon", "Ward",
+            "Gustavo", "Harley", "Peter", "Anibal", "Arlie", "Nigel", "Oren", "Zachary", "Scot", "Bud", "Wilbert",
+            "Bart", "Josiah", "Marlon", "Eldon", "Darryl", "Roger", "Anthony", "Omer", "Francis", "Patricia", "Moises",
+            "Chuck", "Waylon", "Hector", "Jamaal", "Cesar", "Julius", "Rex", "Norris", "Ollie", "Isaias", "Quentin",
+            "Graig", "Lyle", "Jeffry", "Karl", "Lester", "Danilo", "Mike", "Dylan", "Carlo", "Ryan", "Leon", "Percy",
+            "Lucius", "Jamel", "Lesley", "Joey", "Cornelius", "Rico", "Arnulfo", "Chet", "Margarito", "Ernie",
+            "Nathanael", "Amos", "Cleveland", "Luigi", "Alfonzo", "Phillip", "Clair", "Elroy", "Alva", "Hans", "Shon",
+            "Gary", "Jesus", "Cary", "Silas", "Keith", "Israel", "Willard", "Randolph", "Dan", "Adalberto", "Claude",
             "Delbert", "Garry", "Mary", "Larry", "Riley", "Robt", "Darwin", "Barrett", "Steven", "Kelly", "Herschel",
             "Darnell", "Scotty", "Armando", "Miguel", "Lawerence", "Wesley", "Garth", "Carol", "Micah", "Alvin",
             "Billy", "Earl", "Pat", "Brady", "Cory", "Carey", "Bernard", "Jayson", "Nathaniel", "Gaylord", "Archie",
-            "Dorsey", "Erasmo", "Angelo", "Elisha", "Long", "Augustus", "Hobert", "Drew", "Stan", "Sherwood",
-            "Lorenzo", "Forrest", "Shawn", "Leigh", "Hiram", "Leonardo", "Gerry", "Myron", "Hugo", "Alvaro", "Leland",
-            "Genaro", "Jamey", "Stewart", "Elden", "Irving", "Olen", "Antone", "Freddy", "Lupe", "Joshua", "Gregory",
-            "Andrew", "Sang", "Wilbur", "Gerardo", "Merlin", "Williams", "Johnny", "Alex", "Tommie", "Jimmy",
-            "Donovan", "Dexter", "Gaston", "Tracy", "Jeff", "Stephen", "Berry", "Anton", "Darell", "Fritz", "Willis",
-            "Noel", "Mariano", "Crawford", "Zoey", "Alex", "Brianna", "Carlie", "Lloyd", "Cal", "Astor", "Randolf",
-            "Magdalene", "Trevelyan", "Terance", "Roy", "Kermit", "Harriett", "Crystal", "Laurinda", "Kiersten",
-            "Phyllida", "Liz", "Bettie", "Rena", "Colten", "Berenice", "Sindy", "Wilma", "Amos", "Candi", "Ritchie",
-            "Dirk", "Kathlyn", "Callista", "Anona", "Flossie", "Sterling", "Calista", "Regan", "Erica", "Jeana",
-            "Keaton", "York", "Nolan", "Daniel", "Benton", "Tommie", "Serenity", "Deanna", "Chas", "Heron", "Marlyn",
-            "Xylia", "Tristin", "Lyndon", "Andriana", "Madelaine", "Maddison", "Leila", "Chantelle", "Audrey",
-            "Connor", "Daley", "Tracee", "Tilda", "Eliot", "Merle", "Linwood", "Kathryn", "Silas", "Alvina",
-            "Phinehas", "Janis", "Alvena", "Zubin", "Gwendolen", "Caitlyn", "Bertram", "Hailee", "Idelle", "Homer",
-            "Jannah", "Delbert", "Rhianna", "Cy", "Jefferson", "Wayland", "Nona", "Tempest", "Reed", "Jenifer",
-            "Ellery", "Nicolina", "Aldous", "Prince", "Lexia", "Vinnie", "Doug", "Alberic", "Kayleen", "Woody",
-            "Rosanne", "Ysabel", "Skyler", "Twyla", "Geordie", "Leta", "Clive", "Aaron", "Scottie", "Celeste", "Chuck",
-            "Erle", "Lallie", "Jaycob", "Ray", "Carrie", "Laurita", "Noreen", "Meaghan", "Ulysses", "Andy", "Drogo",
-            "Dina", "Yasmin", "Mya", "Luvenia", "Urban", "Jacob", "Laetitia", "Sherry", "Love", "Michaela", "Deonne",
-            "Summer", "Brendon", "Sheena", "Mason", "Jayson", "Linden", "Salal", "Darrell", "Diana", "Hudson",
-            "Lennon", "Isador", "Charley", "April", "Ralph", "James", "Mina", "Jolyon", "Laurine", "Monna", "Carita",
-            "Munro", "Elsdon", "Everette", "Radclyffe", "Darrin", "Herbert", "Gawain", "Sheree", "Trudy", "Emmaline",
-            "Kassandra", "Rebecca", "Basil", "Jen", "Don", "Osborne", "Lilith", "Hannah", "Fox", "Rupert", "Paulene",
-            "Darius", "Wally", "Baptist", "Sapphire", "Tia", "Sondra", "Kylee", "Ashton", "Jepson", "Joetta", "Val",
-            "Adela", "Zacharias", "Zola", "Marmaduke", "Shannah", "Posie", "Oralie", "Brittany", "Ernesta", "Raymund",
-            "Denzil", "Daren", "Roosevelt", "Nelson", "Fortune", "Mariel", "Nick", "Jaden", "Upton", "Oz", "Margaux",
-            "Precious", "Albert", "Bridger", "Jimmy", "Nicola", "Rosalynne", "Keith", "Walt", "Della", "Joanna",
-            "Xenia", "Esmeralda", "Major", "Simon", "Rexana", "Stacy", "Calanthe", "Sherley", "Kaitlyn", "Graham",
-            "Ramsey", "Abbey", "Madlyn", "Kelvin", "Bill", "Rue", "Monica", "Caileigh", "Laraine", "Booker", "Jayna",
-            "Greta", "Jervis", "Sherman", "Kendrick", "Tommy", "Iris", "Geffrey", "Kaelea", "Kerr", "Garrick", "Jep",
-            "Audley", "Nic", "Bronte", "Beulah", "Patricia", "Jewell", "Deidra", "Cory", "Everett", "Harper",
-            "Charity", "Godfrey", "Jaime", "Sinclair", "Talbot", "Dayna", "Cooper", "Rosaline", "Jennie", "Eileen",
-            "Latanya", "Corinna", "Roxie", "Caesar", "Charles", "Pollie", "Lindsey", "Sorrel", "Dwight", "Jocelyn",
-            "Weston", "Shyla", "Valorie", "Bessie", "Josh", "Lessie", "Dayton", "Kathi", "Chasity", "Wilton", "Adam",
-            "William", "Ash", "Angela", "Ivor", "Ria", "Jazmine", "Hailey", "Jo", "Silvestra", "Ernie", "Clifford",
-            "Levi", "Matilda", "Quincey", "Camilla", "Delicia", "Phemie", "Laurena", "Bambi", "Lourdes", "Royston",
-            "Chastity", "Lynwood", "Elle", "Brenda", "Phoebe", "Timothy", "Raschelle", "Lilly", "Burt", "Rina",
-            "Rodney", "Maris", "Jaron", "Wilf", "Harlan", "Audra", "Vincent", "Elwyn", "Drew", "Wynter", "Ora",
-            "Lissa", "Virgil", "Xavier", "Chad", "Ollie", "Leyton", "Karolyn", "Skye", "Roni", "Gladys", "Dinah",
-            "Penny", "August", "Osmund", "Whitaker", "Brande", "Cornell", "Phil", "Zara", "Kilie", "Gavin", "Coty",
-            "Randy", "Teri", "Keira", "Pru", "Clemency", "Kelcey", "Nevil", "Poppy", "Gareth", "Christabel", "Bastian",
-            "Wynonna", "Roselyn", "Goddard", "Collin", "Trace", "Neal", "Effie", "Denys", "Virginia", "Richard",
-            "Isiah", "Harrietta", "Gaylord", "Diamond", "Trudi", "Elaine", "Jemmy", "Gage", "Annabel", "Quincy", "Syd",
-            "Marianna", "Philomena", "Aubree", "Kathie", "Jacki", "Kelley", "Bess", "Cecil", "Maryvonne", "Kassidy",
-            "Anselm", "Dona", "Darby", "Jamison", "Daryl", "Darell", "Teal", "Lennie", "Bartholomew", "Katie",
-            "Maybelline", "Kimball", "Elvis", "Les", "Flick", "Harley", "Beth", "Bidelia", "Montague", "Helen", "Ozzy",
-            "Stef", "Debra", "Maxene", "Stefanie", "Russ", "Avril", "Johnathan", "Orson", "Chelsey", "Josephine",
-            "Deshaun", "Wendell", "Lula", "Ferdinanda", "Greg", "Brad", "Kynaston", "Dena", "Russel", "Robertina",
-            "Misti", "Leon", "Anjelica", "Bryana", "Myles", "Judi", "Curtis", "Davin", "Kristia", "Chrysanta",
-            "Hayleigh", "Hector", "Osbert", "Eustace", "Cary", "Tansy", "Cayley", "Maryann", "Alissa", "Ike",
-            "Tranter", "Reina", "Alwilda", "Sidony", "Columbine", "Astra", "Jillie", "Stephania", "Jonah", "Kennedy",
-            "Ferdinand", "Allegria", "Donella", "Kelleigh", "Darian", "Eldreda", "Jayden", "Herbie", "Jake", "Winston",
-            "Vi", "Annie", "Cherice", "Hugo", "Tricia", "Haydee", "Cassarah", "Darden", "Mallory", "Alton", "Hadley",
-            "Romayne", "Lacey", "Ern", "Alayna", "Cecilia", "Seward", "Tilly", "Edgar", "Concordia", "Ibbie", "Dahlia",
-            "Oswin", "Stu", "Brett", "Maralyn", "Kristeen", "Dotty", "Robyn", "Nessa", "Tresha", "Guinevere",
-            "Emerson", "Haze", "Lyn", "Henderson", "Lexa", "Jaylen", "Gail", "Lizette", "Tiara", "Robbie", "Destiny",
-            "Alice", "Livia", "Rosy", "Leah", "Jan", "Zach", "Vita", "Gia", "Micheal", "Rowina", "Alysha", "Bobbi",
-            "Delores", "Osmond", "Karaugh", "Wilbur", "Kasandra", "Renae", "Kaety", "Dora", "Gaye", "Amaryllis",
-            "Katelyn", "Dacre", "Prudence", "Ebony", "Camron", "Jerrold", "Vivyan", "Randall", "Donna", "Misty",
-            "Damon", "Selby", "Esmund", "Rian", "Garry", "Julius", "Raelene", "Clement", "Dom", "Tibby", "Moss",
-            "Millicent", "Gwendoline", "Berry", "Ashleigh", "Lilac", "Quin", "Vere", "Creighton", "Harriet", "Malvina",
-            "Lianne", "Pearle", "Kizzie", "Kara", "Petula", "Jeanie", "Maria", "Pacey", "Victoria", "Huey", "Toni",
-            "Rose", "Wallis", "Diggory", "Josiah", "Delma", "Keysha", "Channing", "Prue", "Lee", "Ryan", "Sidney",
-            "Valerie", "Clancy", "Ezra", "Gilbert", "Clare", "Laz", "Crofton", "Mike", "Annabella", "Tara", "Eldred",
-            "Arthur", "Jaylon", "Peronel", "Paden", "Dot", "Marian", "Amyas", "Alexus", "Esmond", "Abbie", "Stanley",
-            "Brittani", "Vickie", "Errol", "Kimberlee", "Uland", "Ebenezer", "Howie", "Eveline", "Andrea", "Trish",
-            "Hopkin", "Bryanna", "Temperance", "Valarie", "Femie", "Alix", "Terrell", "Lewin", "Lorrin", "Happy",
-            "Micah", "Rachyl", "Sloan", "Gertrude", "Elizabeth", "Dorris", "Andra", "Bram", "Gary", "Jeannine",
-            "Maurene", "Irene", "Yolonda", "Jonty", "Coleen", "Cecelia", "Chantal", "Stuart", "Caris", "Ros",
-            "Kaleigh", "Mirabelle", "Kolby", "Primrose", "Susannah", "Ginny", "Jinny", "Dolly", "Lettice", "Sonny",
-            "Melva", "Ernest", "Garret", "Reagan", "Trenton", "Gallagher", "Edwin", "Nikolas", "Corrie", "Lynette",
-            "Ettie", "Sly", "Debbi", "Eudora", "Brittney", "Tacey", "Marius", "Anima", "Gordon", "Olivia", "Kortney",
-            "Shantel", "Kolleen", "Nevaeh", "Buck", "Sera", "Liliana", "Aric", "Kalyn", "Mick", "Libby", "Ingram",
-            "Alexandria", "Darleen", "Jacklyn", "Hughie", "Tyler", "Aida", "Ronda", "Deemer", "Taryn", "Laureen",
-            "Samantha", "Dave", "Hardy", "Baldric", "Montgomery", "Gus", "Ellis", "Titania", "Luke", "Chase", "Haidee",
-            "Mayra", "Isabell", "Trinity", "Milo", "Abigail", "Tacita", "Meg", "Hervey", "Natasha", "Sadie", "Holden",
-            "Dee", "Mansel", "Perry", "Randi", "Frederica", "Georgina", "Kolour", "Debbie", "Seraphina", "Elspet",
-            "Julyan", "Raven", "Zavia", "Jarvis", "Jaymes", "Grover", "Cairo", "Alea", "Jordon", "Braxton", "Donny",
-            "Rhoda", "Tonya", "Bee", "Alyssia", "Ashlyn", "Reanna", "Lonny", "Arlene", "Deb", "Jane", "Nikole",
-            "Bettina", "Harrison", "Tamzen", "Arielle", "Adelaide", "Faith", "Bridie", "Wilburn", "Fern", "Nan",
-            "Shaw", "Zeke", "Alan", "Dene", "Gina", "Alexa", "Bailey", "Sal", "Tammy", "Maximillian", "America",
-            "Sylvana", "Fitz", "Mo", "Marissa", "Cass", "Eldon", "Wilfrid", "Tel", "Joann", "Kendra", "Tolly",
-            "Leanne", "Ferdie", "Haven", "Lucas", "Marlee", "Cyrilla", "Red", "Phoenix", "Jazmin", "Carin", "Gena",
-            "Lashonda", "Tucker", "Genette", "Kizzy", "Winifred", "Melody", "Keely", "Kaylyn", "Radcliff", "Lettie",
-            "Foster", "Lyndsey", "Nicholas", "Farley", "Louisa", "Dana", "Dortha", "Francine", "Doran", "Bonita",
-            "Hal", "Sawyer", "Reginald", "Aislin", "Nathan", "Baylee", "Abilene", "Ladonna", "Maurine", "Shelly",
-            "Deandre", "Jasmin", "Roderic", "Tiffany", "Amanda", "Verity", "Wilford", "Gayelord", "Whitney", "Demelza",
-            "Kenton", "Alberta", "Kyra", "Tabitha", "Sampson", "Korey", "Lillian", "Edison", "Clayton", "Steph",
-            "Maya", "Dusty", "Jim", "Ronny", "Adrianne", "Bernard", "Harris", "Kiley", "Alexander", "Kisha", "Ethalyn",
-            "Patience", "Briony", "Indigo", "Aureole", "Makenzie", "Molly", "Sherilyn", "Barry", "Laverne", "Hunter",
-            "Rocky", "Tyreek", "Madalyn", "Phyliss", "Chet", "Beatrice", "Faye", "Lavina", "Madelyn", "Tracey",
-            "Gyles", "Patti", "Carlyn", "Stephanie", "Jackalyn", "Larrie", "Kimmy", "Isolda", "Emelina", "Lis",
-            "Zillah", "Cody", "Sheard", "Rufus", "Paget", "Mae", "Rexanne", "Luvinia", "Tamsen", "Rosanna", "Greig",
-            "Stacia", "Mabelle", "Quianna", "Lotus", "Delice", "Bradford", "Angus", "Cosmo", "Earlene", "Adrian",
-            "Arlie", "Noelle", "Sabella", "Isa", "Adelle", "Innocent", "Kirby", "Trixie", "Kenelm", "Nelda", "Melia",
-            "Kendal", "Dorinda", "Placid", "Linette", "Kam", "Sherisse", "Evan", "Ewart", "Janice", "Linton",
+            "Dorsey", "Erasmo", "Angelo", "Elisha", "Long", "Augustus", "Hobert", "Drew", "Stan", "Sherwood", "Lorenzo",
+            "Forrest", "Shawn", "Leigh", "Hiram", "Leonardo", "Gerry", "Myron", "Hugo", "Alvaro", "Leland", "Genaro",
+            "Jamey", "Stewart", "Elden", "Irving", "Olen", "Antone", "Freddy", "Lupe", "Joshua", "Gregory", "Andrew",
+            "Sang", "Wilbur", "Gerardo", "Merlin", "Williams", "Johnny", "Alex", "Tommie", "Jimmy", "Donovan", "Dexter",
+            "Gaston", "Tracy", "Jeff", "Stephen", "Berry", "Anton", "Darell", "Fritz", "Willis", "Noel", "Mariano",
+            "Crawford", "Zoey", "Alex", "Brianna", "Carlie", "Lloyd", "Cal", "Astor", "Randolf", "Magdalene",
+            "Trevelyan", "Terance", "Roy", "Kermit", "Harriett", "Crystal", "Laurinda", "Kiersten", "Phyllida", "Liz",
+            "Bettie", "Rena", "Colten", "Berenice", "Sindy", "Wilma", "Amos", "Candi", "Ritchie", "Dirk", "Kathlyn",
+            "Callista", "Anona", "Flossie", "Sterling", "Calista", "Regan", "Erica", "Jeana", "Keaton", "York", "Nolan",
+            "Daniel", "Benton", "Tommie", "Serenity", "Deanna", "Chas", "Heron", "Marlyn", "Xylia", "Tristin", "Lyndon",
+            "Andriana", "Madelaine", "Maddison", "Leila", "Chantelle", "Audrey", "Connor", "Daley", "Tracee", "Tilda",
+            "Eliot", "Merle", "Linwood", "Kathryn", "Silas", "Alvina", "Phinehas", "Janis", "Alvena", "Zubin",
+            "Gwendolen", "Caitlyn", "Bertram", "Hailee", "Idelle", "Homer", "Jannah", "Delbert", "Rhianna", "Cy",
+            "Jefferson", "Wayland", "Nona", "Tempest", "Reed", "Jenifer", "Ellery", "Nicolina", "Aldous", "Prince",
+            "Lexia", "Vinnie", "Doug", "Alberic", "Kayleen", "Woody", "Rosanne", "Ysabel", "Skyler", "Twyla", "Geordie",
+            "Leta", "Clive", "Aaron", "Scottie", "Celeste", "Chuck", "Erle", "Lallie", "Jaycob", "Ray", "Carrie",
+            "Laurita", "Noreen", "Meaghan", "Ulysses", "Andy", "Drogo", "Dina", "Yasmin", "Mya", "Luvenia", "Urban",
+            "Jacob", "Laetitia", "Sherry", "Love", "Michaela", "Deonne", "Summer", "Brendon", "Sheena", "Mason",
+            "Jayson", "Linden", "Salal", "Darrell", "Diana", "Hudson", "Lennon", "Isador", "Charley", "April", "Ralph",
+            "James", "Mina", "Jolyon", "Laurine", "Monna", "Carita", "Munro", "Elsdon", "Everette", "Radclyffe",
+            "Darrin", "Herbert", "Gawain", "Sheree", "Trudy", "Emmaline", "Kassandra", "Rebecca", "Basil", "Jen", "Don",
+            "Osborne", "Lilith", "Hannah", "Fox", "Rupert", "Paulene", "Darius", "Wally", "Baptist", "Sapphire", "Tia",
+            "Sondra", "Kylee", "Ashton", "Jepson", "Joetta", "Val", "Adela", "Zacharias", "Zola", "Marmaduke",
+            "Shannah", "Posie", "Oralie", "Brittany", "Ernesta", "Raymund", "Denzil", "Daren", "Roosevelt", "Nelson",
+            "Fortune", "Mariel", "Nick", "Jaden", "Upton", "Oz", "Margaux", "Precious", "Albert", "Bridger", "Jimmy",
+            "Nicola", "Rosalynne", "Keith", "Walt", "Della", "Joanna", "Xenia", "Esmeralda", "Major", "Simon", "Rexana",
+            "Stacy", "Calanthe", "Sherley", "Kaitlyn", "Graham", "Ramsey", "Abbey", "Madlyn", "Kelvin", "Bill", "Rue",
+            "Monica", "Caileigh", "Laraine", "Booker", "Jayna", "Greta", "Jervis", "Sherman", "Kendrick", "Tommy",
+            "Iris", "Geffrey", "Kaelea", "Kerr", "Garrick", "Jep", "Audley", "Nic", "Bronte", "Beulah", "Patricia",
+            "Jewell", "Deidra", "Cory", "Everett", "Harper", "Charity", "Godfrey", "Jaime", "Sinclair", "Talbot",
+            "Dayna", "Cooper", "Rosaline", "Jennie", "Eileen", "Latanya", "Corinna", "Roxie", "Caesar", "Charles",
+            "Pollie", "Lindsey", "Sorrel", "Dwight", "Jocelyn", "Weston", "Shyla", "Valorie", "Bessie", "Josh",
+            "Lessie", "Dayton", "Kathi", "Chasity", "Wilton", "Adam", "William", "Ash", "Angela", "Ivor", "Ria",
+            "Jazmine", "Hailey", "Jo", "Silvestra", "Ernie", "Clifford", "Levi", "Matilda", "Quincey", "Camilla",
+            "Delicia", "Phemie", "Laurena", "Bambi", "Lourdes", "Royston", "Chastity", "Lynwood", "Elle", "Brenda",
+            "Phoebe", "Timothy", "Raschelle", "Lilly", "Burt", "Rina", "Rodney", "Maris", "Jaron", "Wilf", "Harlan",
+            "Audra", "Vincent", "Elwyn", "Drew", "Wynter", "Ora", "Lissa", "Virgil", "Xavier", "Chad", "Ollie",
+            "Leyton", "Karolyn", "Skye", "Roni", "Gladys", "Dinah", "Penny", "August", "Osmund", "Whitaker", "Brande",
+            "Cornell", "Phil", "Zara", "Kilie", "Gavin", "Coty", "Randy", "Teri", "Keira", "Pru", "Clemency", "Kelcey",
+            "Nevil", "Poppy", "Gareth", "Christabel", "Bastian", "Wynonna", "Roselyn", "Goddard", "Collin", "Trace",
+            "Neal", "Effie", "Denys", "Virginia", "Richard", "Isiah", "Harrietta", "Gaylord", "Diamond", "Trudi",
+            "Elaine", "Jemmy", "Gage", "Annabel", "Quincy", "Syd", "Marianna", "Philomena", "Aubree", "Kathie", "Jacki",
+            "Kelley", "Bess", "Cecil", "Maryvonne", "Kassidy", "Anselm", "Dona", "Darby", "Jamison", "Daryl", "Darell",
+            "Teal", "Lennie", "Bartholomew", "Katie", "Maybelline", "Kimball", "Elvis", "Les", "Flick", "Harley",
+            "Beth", "Bidelia", "Montague", "Helen", "Ozzy", "Stef", "Debra", "Maxene", "Stefanie", "Russ", "Avril",
+            "Johnathan", "Orson", "Chelsey", "Josephine", "Deshaun", "Wendell", "Lula", "Ferdinanda", "Greg", "Brad",
+            "Kynaston", "Dena", "Russel", "Robertina", "Misti", "Leon", "Anjelica", "Bryana", "Myles", "Judi", "Curtis",
+            "Davin", "Kristia", "Chrysanta", "Hayleigh", "Hector", "Osbert", "Eustace", "Cary", "Tansy", "Cayley",
+            "Maryann", "Alissa", "Ike", "Tranter", "Reina", "Alwilda", "Sidony", "Columbine", "Astra", "Jillie",
+            "Stephania", "Jonah", "Kennedy", "Ferdinand", "Allegria", "Donella", "Kelleigh", "Darian", "Eldreda",
+            "Jayden", "Herbie", "Jake", "Winston", "Vi", "Annie", "Cherice", "Hugo", "Tricia", "Haydee", "Cassarah",
+            "Darden", "Mallory", "Alton", "Hadley", "Romayne", "Lacey", "Ern", "Alayna", "Cecilia", "Seward", "Tilly",
+            "Edgar", "Concordia", "Ibbie", "Dahlia", "Oswin", "Stu", "Brett", "Maralyn", "Kristeen", "Dotty", "Robyn",
+            "Nessa", "Tresha", "Guinevere", "Emerson", "Haze", "Lyn", "Henderson", "Lexa", "Jaylen", "Gail", "Lizette",
+            "Tiara", "Robbie", "Destiny", "Alice", "Livia", "Rosy", "Leah", "Jan", "Zach", "Vita", "Gia", "Micheal",
+            "Rowina", "Alysha", "Bobbi", "Delores", "Osmond", "Karaugh", "Wilbur", "Kasandra", "Renae", "Kaety", "Dora",
+            "Gaye", "Amaryllis", "Katelyn", "Dacre", "Prudence", "Ebony", "Camron", "Jerrold", "Vivyan", "Randall",
+            "Donna", "Misty", "Damon", "Selby", "Esmund", "Rian", "Garry", "Julius", "Raelene", "Clement", "Dom",
+            "Tibby", "Moss", "Millicent", "Gwendoline", "Berry", "Ashleigh", "Lilac", "Quin", "Vere", "Creighton",
+            "Harriet", "Malvina", "Lianne", "Pearle", "Kizzie", "Kara", "Petula", "Jeanie", "Maria", "Pacey",
+            "Victoria", "Huey", "Toni", "Rose", "Wallis", "Diggory", "Josiah", "Delma", "Keysha", "Channing", "Prue",
+            "Lee", "Ryan", "Sidney", "Valerie", "Clancy", "Ezra", "Gilbert", "Clare", "Laz", "Crofton", "Mike",
+            "Annabella", "Tara", "Eldred", "Arthur", "Jaylon", "Peronel", "Paden", "Dot", "Marian", "Amyas", "Alexus",
+            "Esmond", "Abbie", "Stanley", "Brittani", "Vickie", "Errol", "Kimberlee", "Uland", "Ebenezer", "Howie",
+            "Eveline", "Andrea", "Trish", "Hopkin", "Bryanna", "Temperance", "Valarie", "Femie", "Alix", "Terrell",
+            "Lewin", "Lorrin", "Happy", "Micah", "Rachyl", "Sloan", "Gertrude", "Elizabeth", "Dorris", "Andra", "Bram",
+            "Gary", "Jeannine", "Maurene", "Irene", "Yolonda", "Jonty", "Coleen", "Cecelia", "Chantal", "Stuart",
+            "Caris", "Ros", "Kaleigh", "Mirabelle", "Kolby", "Primrose", "Susannah", "Ginny", "Jinny", "Dolly",
+            "Lettice", "Sonny", "Melva", "Ernest", "Garret", "Reagan", "Trenton", "Gallagher", "Edwin", "Nikolas",
+            "Corrie", "Lynette", "Ettie", "Sly", "Debbi", "Eudora", "Brittney", "Tacey", "Marius", "Anima", "Gordon",
+            "Olivia", "Kortney", "Shantel", "Kolleen", "Nevaeh", "Buck", "Sera", "Liliana", "Aric", "Kalyn", "Mick",
+            "Libby", "Ingram", "Alexandria", "Darleen", "Jacklyn", "Hughie", "Tyler", "Aida", "Ronda", "Deemer",
+            "Taryn", "Laureen", "Samantha", "Dave", "Hardy", "Baldric", "Montgomery", "Gus", "Ellis", "Titania", "Luke",
+            "Chase", "Haidee", "Mayra", "Isabell", "Trinity", "Milo", "Abigail", "Tacita", "Meg", "Hervey", "Natasha",
+            "Sadie", "Holden", "Dee", "Mansel", "Perry", "Randi", "Frederica", "Georgina", "Kolour", "Debbie",
+            "Seraphina", "Elspet", "Julyan", "Raven", "Zavia", "Jarvis", "Jaymes", "Grover", "Cairo", "Alea", "Jordon",
+            "Braxton", "Donny", "Rhoda", "Tonya", "Bee", "Alyssia", "Ashlyn", "Reanna", "Lonny", "Arlene", "Deb",
+            "Jane", "Nikole", "Bettina", "Harrison", "Tamzen", "Arielle", "Adelaide", "Faith", "Bridie", "Wilburn",
+            "Fern", "Nan", "Shaw", "Zeke", "Alan", "Dene", "Gina", "Alexa", "Bailey", "Sal", "Tammy", "Maximillian",
+            "America", "Sylvana", "Fitz", "Mo", "Marissa", "Cass", "Eldon", "Wilfrid", "Tel", "Joann", "Kendra",
+            "Tolly", "Leanne", "Ferdie", "Haven", "Lucas", "Marlee", "Cyrilla", "Red", "Phoenix", "Jazmin", "Carin",
+            "Gena", "Lashonda", "Tucker", "Genette", "Kizzy", "Winifred", "Melody", "Keely", "Kaylyn", "Radcliff",
+            "Lettie", "Foster", "Lyndsey", "Nicholas", "Farley", "Louisa", "Dana", "Dortha", "Francine", "Doran",
+            "Bonita", "Hal", "Sawyer", "Reginald", "Aislin", "Nathan", "Baylee", "Abilene", "Ladonna", "Maurine",
+            "Shelly", "Deandre", "Jasmin", "Roderic", "Tiffany", "Amanda", "Verity", "Wilford", "Gayelord", "Whitney",
+            "Demelza", "Kenton", "Alberta", "Kyra", "Tabitha", "Sampson", "Korey", "Lillian", "Edison", "Clayton",
+            "Steph", "Maya", "Dusty", "Jim", "Ronny", "Adrianne", "Bernard", "Harris", "Kiley", "Alexander", "Kisha",
+            "Ethalyn", "Patience", "Briony", "Indigo", "Aureole", "Makenzie", "Molly", "Sherilyn", "Barry", "Laverne",
+            "Hunter", "Rocky", "Tyreek", "Madalyn", "Phyliss", "Chet", "Beatrice", "Faye", "Lavina", "Madelyn",
+            "Tracey", "Gyles", "Patti", "Carlyn", "Stephanie", "Jackalyn", "Larrie", "Kimmy", "Isolda", "Emelina",
+            "Lis", "Zillah", "Cody", "Sheard", "Rufus", "Paget", "Mae", "Rexanne", "Luvinia", "Tamsen", "Rosanna",
+            "Greig", "Stacia", "Mabelle", "Quianna", "Lotus", "Delice", "Bradford", "Angus", "Cosmo", "Earlene",
+            "Adrian", "Arlie", "Noelle", "Sabella", "Isa", "Adelle", "Innocent", "Kirby", "Trixie", "Kenelm", "Nelda",
+            "Melia", "Kendal", "Dorinda", "Placid", "Linette", "Kam", "Sherisse", "Evan", "Ewart", "Janice", "Linton",
             "Jacaline", "Charissa", "Douglas", "Aileen", "Kemp", "Oli", "Amethyst", "Rosie", "Nigella", "Sherill",
             "Anderson", "Alanna", "Eric", "Claudia", "Jennifer", "Boniface", "Harriet", "Vernon", "Lucy", "Shawnee",
             "Gerard", "Cecily", "Romey", "Randall", "Wade", "Lux", "Dawson", "Gregg", "Kade", "Roxanne", "Melinda",
@@ -1089,83 +1093,82 @@
             "Sammi", "Gall", "Chloe", "Ottoline", "Herbert", "Janice", "Gareth", "Channing", "Caleigh", "Kailee",
             "Ralphie", "Tamzen", "Quincy", "Beaumont", "Albert", "Jadyn", "Violet", "Luanna", "Moriah", "Humbert",
             "Jed", "Leona", "Hale", "Mitch", "Marlin", "Nivek", "Darwin", "Dirk", "Liliana", "Meadow", "Bernadine",
-            "Jorie", "Peyton", "Astra", "Roscoe", "Gina", "Lovell", "Jewel", "Romayne", "Rosy", "Imogene",
-            "Margaretta", "Lorinda", "Hopkin", "Bobby", "Flossie", "Bennie", "Horatio", "Jonah", "Lyn", "Deana",
-            "Juliana", "Blanch", "Wright", "Kendal", "Woodrow", "Tania", "Austyn", "Val", "Mona", "Charla", "Rudyard",
-            "Pamela", "Raven", "Zena", "Nicola", "Kaelea", "Conor", "Virgil", "Sonnie", "Goodwin", "Christianne",
-            "Linford", "Myron", "Denton", "Charita", "Brody", "Ginnie", "Harrison", "Jeanine", "Quin", "Isolda",
-            "Zoie", "Pearce", "Margie", "Larrie", "Angelina", "Marcia", "Jessamine", "Delilah", "Dick", "Luana",
-            "Delicia", "Lake", "Luvenia", "Vaughan", "Concordia", "Gayelord", "Cheyenne", "Felix", "Dorris", "Pen",
-            "Kristeen", "Parris", "Everitt", "Josephina", "Amy", "Tommie", "Adrian", "April", "Rosaline", "Zachery",
-            "Trace", "Phoebe", "Jenelle", "Kameron", "Katharine", "Media", "Colton", "Tad", "Quianna", "Kerenza",
-            "Greta", "Luvinia", "Pete", "Tonya", "Beckah", "Barbra", "Jon", "Tetty", "Corey", "Sylvana", "Kizzy",
-            "Korey", "Trey", "Haydee", "Penny", "Mandy", "Panda", "Coline", "Ramsey", "Sukie", "Annabel", "Sarina",
-            "Corbin", "Suzanna", "Rob", "Duana", "Shell", "Jason", "Eddy", "Rube", "Roseann", "Celia", "Brianne",
-            "Nerissa", "Jera", "Humphry", "Ashlynn", "Terrence", "Philippina", "Coreen", "Kolour", "Indiana", "Paget",
-            "Marlyn", "Hester", "Isbel", "Ocean", "Harris", "Leslie", "Vere", "Monroe", "Isabelle", "Bertie", "Clitus",
-            "Dave", "Alethea", "Lessie", "Louiza", "Madlyn", "Garland", "Wolf", "Lalo", "Donny", "Amabel", "Tianna",
-            "Louie", "Susie", "Mackenzie", "Renie", "Tess", "Marmaduke", "Gwendolen", "Bettina", "Beatrix", "Esmund",
-            "Minnie", "Carlie", "Barnabas", "Ruthie", "Honour", "Haylie", "Xavior", "Freddie", "Ericka", "Aretha",
-            "Edie", "Madelina", "Anson", "Tabby", "Derrick", "Jocosa", "Deirdre", "Aislin", "Chastity", "Abigail",
-            "Wynonna", "Zo", "Eldon", "Krystine", "Ghislaine", "Zavia", "Nolene", "Marigold", "Kelley", "Sylvester",
-            "Odell", "George", "Laurene", "Franklyn", "Clarice", "Mo", "Dustin", "Debbi", "Lina", "Tony", "Acacia",
-            "Hettie", "Natalee", "Marcie", "Brittany", "Elnora", "Rachel", "Dawn", "Basil", "Christal", "Anjelica",
-            "Fran", "Tawny", "Delroy", "Tameka", "Lillie", "Ceara", "Deanna", "Deshaun", "Ken", "Bradford", "Justina",
-            "Merle", "Draven", "Gretta", "Harriette", "Webster", "Nathaniel", "Anemone", "Coleen", "Ruth", "Chryssa",
-            "Hortensia", "Saffie", "Deonne", "Leopold", "Harlan", "Lea", "Eppie", "Lucinda", "Tilda", "Fanny", "Titty",
-            "Lockie", "Jepson", "Sherisse", "Maralyn", "Ethel", "Sly", "Ebenezer", "Canute", "Ella", "Freeman",
-            "Reuben", "Olivette", "Nona", "Rik", "Amice", "Kristine", "Kathie", "Jayne", "Jeri", "Mckenna", "Bertram",
-            "Kaylee", "Livia", "Gil", "Wallace", "Maryann", "Keeleigh", "Laurinda", "Doran", "Khloe", "Dakota",
-            "Yaron", "Kimberleigh", "Gytha", "Doris", "Marylyn", "Benton", "Linnette", "Esther", "Jakki", "Rowina",
-            "Marian", "Roselyn", "Norbert", "Maggie", "Caesar", "Phinehas", "Jerry", "Jasmine", "Antonette", "Miriam",
-            "Monna", "Maryvonne", "Jacquetta", "Bernetta", "Napier", "Annie", "Gladwin", "Sheldon", "Aric", "Elouise",
-            "Gawain", "Kristia", "Gabe", "Kyra", "Red", "Tod", "Dudley", "Lorraine", "Ryley", "Sabina", "Poppy",
-            "Leland", "Aileen", "Eglantine", "Alicia", "Jeni", "Addy", "Tiffany", "Geffrey", "Lavina", "Collin",
-            "Clover", "Vin", "Jerome", "Doug", "Vincent", "Florence", "Scarlet", "Celeste", "Desdemona", "Tiphanie",
-            "Kassandra", "Ashton", "Madison", "Art", "Magdalene", "Iona", "Josepha", "Anise", "Ferne", "Derek",
-            "Huffie", "Qiana", "Ysabel", "Tami", "Shannah", "Xavier", "Willard", "Winthrop", "Vickie", "Maura",
-            "Placid", "Tiara", "Reggie", "Elissa", "Isa", "Chrysanta", "Jeff", "Bessie", "Terri", "Amilia", "Brett",
-            "Daniella", "Damion", "Carolina", "Maximillian", "Travers", "Benjamin", "Oprah", "Darcy", "Yolanda",
-            "Nicolina", "Crofton", "Jarrett", "Kaitlin", "Shauna", "Keren", "Bevis", "Kalysta", "Sharron", "Alyssa",
-            "Blythe", "Zelma", "Caelie", "Norwood", "Billie", "Patrick", "Gary", "Cambria", "Tylar", "Mason", "Helen",
-            "Melyssa", "Gene", "Gilberta", "Carter", "Herbie", "Harmonie", "Leola", "Eugenia", "Clint", "Pauletta",
-            "Edwyna", "Georgina", "Teal", "Harper", "Izzy", "Dillon", "Kezia", "Evangeline", "Colene", "Madelaine",
-            "Zilla", "Rudy", "Dottie", "Caris", "Morton", "Marge", "Tacey", "Parker", "Troy", "Liza", "Lewin",
-            "Tracie", "Justine", "Dallas", "Linden", "Ray", "Loretta", "Teri", "Elvis", "Diane", "Julianna", "Manfred",
-            "Denise", "Eireen", "Ann", "Kenith", "Linwood", "Kathlyn", "Bernice", "Shelley", "Oswald", "Amedeus",
-            "Homer", "Tanzi", "Ted", "Ralphina", "Hyacinth", "Lotus", "Matthias", "Arlette", "Clark", "Cecil",
-            "Elspeth", "Alvena", "Noah", "Millard", "Brenden", "Cole", "Philipa", "Nina", "Thelma", "Iantha", "Reid",
-            "Jefferson", "Meg", "Elsie", "Shirlee", "Nathan", "Nancy", "Simona", "Racheal", "Carin", "Emory", "Delice",
-            "Kristi", "Karaugh", "Kaety", "Tilly", "Em", "Alanis", "Darrin", "Jerrie", "Hollis", "Cary", "Marly",
-            "Carita", "Jody", "Farley", "Hervey", "Rosalin", "Cuthbert", "Stewart", "Jodene", "Caileigh", "Briscoe",
-            "Dolores", "Sheree", "Eustace", "Nigel", "Detta", "Barret", "Rowland", "Kenny", "Githa", "Zoey", "Adela",
-            "Petronella", "Opal", "Coleman", "Niles", "Cyril", "Dona", "Alberic", "Allannah", "Jules", "Avalon",
-            "Hadley", "Thomas", "Renita", "Calanthe", "Heron", "Shawnda", "Chet", "Malina", "Manny", "Rina", "Frieda",
-            "Eveleen", "Deshawn", "Amos", "Raelene", "Paige", "Molly", "Nannie", "Ileen", "Brendon", "Milford",
-            "Unice", "Rebeccah", "Caedmon", "Gae", "Doreen", "Vivian", "Louis", "Raphael", "Vergil", "Lise", "Glenn",
-            "Karyn", "Terance", "Reina", "Jake", "Gordon", "Wisdom", "Isiah", "Gervase", "Fern", "Marylou", "Roddy",
-            "Justy", "Derick", "Shantelle", "Adam", "Chantel", "Madoline", "Emmerson", "Lexie", "Mickey", "Stephen",
-            "Dane", "Stacee", "Elwin", "Tracey", "Alexandra", "Ricky", "Ian", "Kasey", "Rita", "Alanna", "Georgene",
-            "Deon", "Zavier", "Ophelia", "Deforest", "Lowell", "Zubin", "Hardy", "Osmund", "Tabatha", "Debby",
-            "Katlyn", "Tallulah", "Priscilla", "Braden", "Wil", "Keziah", "Jen", "Aggie", "Korbin", "Lemoine",
-            "Barnaby", "Tranter", "Goldie", "Roderick", "Trina", "Emery", "Pris", "Sidony", "Adelle", "Tate", "Wilf",
-            "Zola", "Brande", "Chris", "Calanthia", "Lilly", "Kaycee", "Lashonda", "Jasmin", "Elijah", "Shantel",
-            "Simon", "Rosalind", "Jarod", "Kaylie", "Corrine", "Joselyn", "Archibald", "Mariabella", "Winton",
-            "Merlin", "Chad", "Ursula", "Kristopher", "Hewie", "Adrianna", "Lyndsay", "Jasmyn", "Tim", "Evette",
-            "Margaret", "Samson", "Bronte", "Terence", "Leila", "Candice", "Tori", "Jamey", "Coriander", "Conrad",
-            "Floyd", "Karen", "Lorin", "Maximilian", "Cairo", "Emily", "Yasmin", "Karolyn", "Bryan", "Lanny",
-            "Kimberly", "Rick", "Chaz", "Krystle", "Lyric", "Laura", "Garrick", "Flip", "Monty", "Brendan",
-            "Ermintrude", "Rayner", "Merla", "Titus", "Marva", "Patricia", "Leone", "Tracy", "Jaqueline", "Hallam",
-            "Delores", "Cressida", "Carlyle", "Leann", "Kelcey", "Laurence", "Ryan", "Reynold", "Mark", "Collyn",
-            "Audie", "Sammy", "Ellery", "Sallie", "Pamelia", "Adolph", "Lydia", "Titania", "Ron", "Bridger", "Aline",
-            "Read", "Kelleigh", "Weldon", "Irving", "Garey", "Diggory", "Evander", "Kylee", "Deidre", "Ormond",
+            "Jorie", "Peyton", "Astra", "Roscoe", "Gina", "Lovell", "Jewel", "Romayne", "Rosy", "Imogene", "Margaretta",
+            "Lorinda", "Hopkin", "Bobby", "Flossie", "Bennie", "Horatio", "Jonah", "Lyn", "Deana", "Juliana", "Blanch",
+            "Wright", "Kendal", "Woodrow", "Tania", "Austyn", "Val", "Mona", "Charla", "Rudyard", "Pamela", "Raven",
+            "Zena", "Nicola", "Kaelea", "Conor", "Virgil", "Sonnie", "Goodwin", "Christianne", "Linford", "Myron",
+            "Denton", "Charita", "Brody", "Ginnie", "Harrison", "Jeanine", "Quin", "Isolda", "Zoie", "Pearce", "Margie",
+            "Larrie", "Angelina", "Marcia", "Jessamine", "Delilah", "Dick", "Luana", "Delicia", "Lake", "Luvenia",
+            "Vaughan", "Concordia", "Gayelord", "Cheyenne", "Felix", "Dorris", "Pen", "Kristeen", "Parris", "Everitt",
+            "Josephina", "Amy", "Tommie", "Adrian", "April", "Rosaline", "Zachery", "Trace", "Phoebe", "Jenelle",
+            "Kameron", "Katharine", "Media", "Colton", "Tad", "Quianna", "Kerenza", "Greta", "Luvinia", "Pete", "Tonya",
+            "Beckah", "Barbra", "Jon", "Tetty", "Corey", "Sylvana", "Kizzy", "Korey", "Trey", "Haydee", "Penny",
+            "Mandy", "Panda", "Coline", "Ramsey", "Sukie", "Annabel", "Sarina", "Corbin", "Suzanna", "Rob", "Duana",
+            "Shell", "Jason", "Eddy", "Rube", "Roseann", "Celia", "Brianne", "Nerissa", "Jera", "Humphry", "Ashlynn",
+            "Terrence", "Philippina", "Coreen", "Kolour", "Indiana", "Paget", "Marlyn", "Hester", "Isbel", "Ocean",
+            "Harris", "Leslie", "Vere", "Monroe", "Isabelle", "Bertie", "Clitus", "Dave", "Alethea", "Lessie", "Louiza",
+            "Madlyn", "Garland", "Wolf", "Lalo", "Donny", "Amabel", "Tianna", "Louie", "Susie", "Mackenzie", "Renie",
+            "Tess", "Marmaduke", "Gwendolen", "Bettina", "Beatrix", "Esmund", "Minnie", "Carlie", "Barnabas", "Ruthie",
+            "Honour", "Haylie", "Xavior", "Freddie", "Ericka", "Aretha", "Edie", "Madelina", "Anson", "Tabby",
+            "Derrick", "Jocosa", "Deirdre", "Aislin", "Chastity", "Abigail", "Wynonna", "Zo", "Eldon", "Krystine",
+            "Ghislaine", "Zavia", "Nolene", "Marigold", "Kelley", "Sylvester", "Odell", "George", "Laurene", "Franklyn",
+            "Clarice", "Mo", "Dustin", "Debbi", "Lina", "Tony", "Acacia", "Hettie", "Natalee", "Marcie", "Brittany",
+            "Elnora", "Rachel", "Dawn", "Basil", "Christal", "Anjelica", "Fran", "Tawny", "Delroy", "Tameka", "Lillie",
+            "Ceara", "Deanna", "Deshaun", "Ken", "Bradford", "Justina", "Merle", "Draven", "Gretta", "Harriette",
+            "Webster", "Nathaniel", "Anemone", "Coleen", "Ruth", "Chryssa", "Hortensia", "Saffie", "Deonne", "Leopold",
+            "Harlan", "Lea", "Eppie", "Lucinda", "Tilda", "Fanny", "Titty", "Lockie", "Jepson", "Sherisse", "Maralyn",
+            "Ethel", "Sly", "Ebenezer", "Canute", "Ella", "Freeman", "Reuben", "Olivette", "Nona", "Rik", "Amice",
+            "Kristine", "Kathie", "Jayne", "Jeri", "Mckenna", "Bertram", "Kaylee", "Livia", "Gil", "Wallace", "Maryann",
+            "Keeleigh", "Laurinda", "Doran", "Khloe", "Dakota", "Yaron", "Kimberleigh", "Gytha", "Doris", "Marylyn",
+            "Benton", "Linnette", "Esther", "Jakki", "Rowina", "Marian", "Roselyn", "Norbert", "Maggie", "Caesar",
+            "Phinehas", "Jerry", "Jasmine", "Antonette", "Miriam", "Monna", "Maryvonne", "Jacquetta", "Bernetta",
+            "Napier", "Annie", "Gladwin", "Sheldon", "Aric", "Elouise", "Gawain", "Kristia", "Gabe", "Kyra", "Red",
+            "Tod", "Dudley", "Lorraine", "Ryley", "Sabina", "Poppy", "Leland", "Aileen", "Eglantine", "Alicia", "Jeni",
+            "Addy", "Tiffany", "Geffrey", "Lavina", "Collin", "Clover", "Vin", "Jerome", "Doug", "Vincent", "Florence",
+            "Scarlet", "Celeste", "Desdemona", "Tiphanie", "Kassandra", "Ashton", "Madison", "Art", "Magdalene", "Iona",
+            "Josepha", "Anise", "Ferne", "Derek", "Huffie", "Qiana", "Ysabel", "Tami", "Shannah", "Xavier", "Willard",
+            "Winthrop", "Vickie", "Maura", "Placid", "Tiara", "Reggie", "Elissa", "Isa", "Chrysanta", "Jeff", "Bessie",
+            "Terri", "Amilia", "Brett", "Daniella", "Damion", "Carolina", "Maximillian", "Travers", "Benjamin", "Oprah",
+            "Darcy", "Yolanda", "Nicolina", "Crofton", "Jarrett", "Kaitlin", "Shauna", "Keren", "Bevis", "Kalysta",
+            "Sharron", "Alyssa", "Blythe", "Zelma", "Caelie", "Norwood", "Billie", "Patrick", "Gary", "Cambria",
+            "Tylar", "Mason", "Helen", "Melyssa", "Gene", "Gilberta", "Carter", "Herbie", "Harmonie", "Leola",
+            "Eugenia", "Clint", "Pauletta", "Edwyna", "Georgina", "Teal", "Harper", "Izzy", "Dillon", "Kezia",
+            "Evangeline", "Colene", "Madelaine", "Zilla", "Rudy", "Dottie", "Caris", "Morton", "Marge", "Tacey",
+            "Parker", "Troy", "Liza", "Lewin", "Tracie", "Justine", "Dallas", "Linden", "Ray", "Loretta", "Teri",
+            "Elvis", "Diane", "Julianna", "Manfred", "Denise", "Eireen", "Ann", "Kenith", "Linwood", "Kathlyn",
+            "Bernice", "Shelley", "Oswald", "Amedeus", "Homer", "Tanzi", "Ted", "Ralphina", "Hyacinth", "Lotus",
+            "Matthias", "Arlette", "Clark", "Cecil", "Elspeth", "Alvena", "Noah", "Millard", "Brenden", "Cole",
+            "Philipa", "Nina", "Thelma", "Iantha", "Reid", "Jefferson", "Meg", "Elsie", "Shirlee", "Nathan", "Nancy",
+            "Simona", "Racheal", "Carin", "Emory", "Delice", "Kristi", "Karaugh", "Kaety", "Tilly", "Em", "Alanis",
+            "Darrin", "Jerrie", "Hollis", "Cary", "Marly", "Carita", "Jody", "Farley", "Hervey", "Rosalin", "Cuthbert",
+            "Stewart", "Jodene", "Caileigh", "Briscoe", "Dolores", "Sheree", "Eustace", "Nigel", "Detta", "Barret",
+            "Rowland", "Kenny", "Githa", "Zoey", "Adela", "Petronella", "Opal", "Coleman", "Niles", "Cyril", "Dona",
+            "Alberic", "Allannah", "Jules", "Avalon", "Hadley", "Thomas", "Renita", "Calanthe", "Heron", "Shawnda",
+            "Chet", "Malina", "Manny", "Rina", "Frieda", "Eveleen", "Deshawn", "Amos", "Raelene", "Paige", "Molly",
+            "Nannie", "Ileen", "Brendon", "Milford", "Unice", "Rebeccah", "Caedmon", "Gae", "Doreen", "Vivian", "Louis",
+            "Raphael", "Vergil", "Lise", "Glenn", "Karyn", "Terance", "Reina", "Jake", "Gordon", "Wisdom", "Isiah",
+            "Gervase", "Fern", "Marylou", "Roddy", "Justy", "Derick", "Shantelle", "Adam", "Chantel", "Madoline",
+            "Emmerson", "Lexie", "Mickey", "Stephen", "Dane", "Stacee", "Elwin", "Tracey", "Alexandra", "Ricky", "Ian",
+            "Kasey", "Rita", "Alanna", "Georgene", "Deon", "Zavier", "Ophelia", "Deforest", "Lowell", "Zubin", "Hardy",
+            "Osmund", "Tabatha", "Debby", "Katlyn", "Tallulah", "Priscilla", "Braden", "Wil", "Keziah", "Jen", "Aggie",
+            "Korbin", "Lemoine", "Barnaby", "Tranter", "Goldie", "Roderick", "Trina", "Emery", "Pris", "Sidony",
+            "Adelle", "Tate", "Wilf", "Zola", "Brande", "Chris", "Calanthia", "Lilly", "Kaycee", "Lashonda", "Jasmin",
+            "Elijah", "Shantel", "Simon", "Rosalind", "Jarod", "Kaylie", "Corrine", "Joselyn", "Archibald",
+            "Mariabella", "Winton", "Merlin", "Chad", "Ursula", "Kristopher", "Hewie", "Adrianna", "Lyndsay", "Jasmyn",
+            "Tim", "Evette", "Margaret", "Samson", "Bronte", "Terence", "Leila", "Candice", "Tori", "Jamey",
+            "Coriander", "Conrad", "Floyd", "Karen", "Lorin", "Maximilian", "Cairo", "Emily", "Yasmin", "Karolyn",
+            "Bryan", "Lanny", "Kimberly", "Rick", "Chaz", "Krystle", "Lyric", "Laura", "Garrick", "Flip", "Monty",
+            "Brendan", "Ermintrude", "Rayner", "Merla", "Titus", "Marva", "Patricia", "Leone", "Tracy", "Jaqueline",
+            "Hallam", "Delores", "Cressida", "Carlyle", "Leann", "Kelcey", "Laurence", "Ryan", "Reynold", "Mark",
+            "Collyn", "Audie", "Sammy", "Ellery", "Sallie", "Pamelia", "Adolph", "Lydia", "Titania", "Ron", "Bridger",
+            "Aline", "Read", "Kelleigh", "Weldon", "Irving", "Garey", "Diggory", "Evander", "Kylee", "Deidre", "Ormond",
             "Laurine", "Reannon", "Arline", "Pat"
 
     };
 
-    public static String[] jargon = { "wireless", "signal", "network", "3G", "plan", "touch-screen",
-            "customer-service", "reachability", "voice-command", "shortcut-menu", "customization", "platform", "speed",
-            "voice-clarity", "voicemail-service" };
+    public static String[] jargon = { "wireless", "signal", "network", "3G", "plan", "touch-screen", "customer-service",
+            "reachability", "voice-command", "shortcut-menu", "customization", "platform", "speed", "voice-clarity",
+            "voicemail-service" };
 
     public static String[] vendors = { "at&t", "verizon", "t-mobile", "sprint", "motorola", "samsung", "iphone" };
 
diff --git a/asterix-tools/src/main/java/org/apache/asterix/tools/external/data/DataGeneratorForSpatialIndexEvaluation.java b/asterix-tools/src/main/java/org/apache/asterix/tools/external/data/DataGeneratorForSpatialIndexEvaluation.java
new file mode 100644
index 0000000..93ffe59
--- /dev/null
+++ b/asterix-tools/src/main/java/org/apache/asterix/tools/external/data/DataGeneratorForSpatialIndexEvaluation.java
@@ -0,0 +1,1341 @@
+/*
+ * 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.asterix.tools.external.data;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.CharBuffer;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.asterix.external.util.DataGenerator;
+
+public class DataGeneratorForSpatialIndexEvaluation {
+
+    private static final String DUMMY_SIZE_ADJUSTER = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+
+    private RandomDateGenerator randDateGen;
+
+    private RandomNameGenerator randNameGen;
+
+    private RandomMessageGenerator randMessageGen;
+
+    private RandomLocationGenerator randLocationGen;
+
+    private LocationGeneratorFromOpenStreetMapData locationGenFromOpenStreetMapData;
+
+    private Random random = new Random();
+
+    private TwitterUser twUser = new TwitterUser();
+
+    private TweetMessage twMessage = new TweetMessage();
+
+    public DataGeneratorForSpatialIndexEvaluation(InitializationInfo info) {
+        initialize(info, null, 0);
+    }
+
+    public DataGeneratorForSpatialIndexEvaluation(InitializationInfo info, String openStreetMapFilePath,
+            int locationSampleInterval) {
+        initialize(info, openStreetMapFilePath, locationSampleInterval);
+    }
+
+    public class TweetMessageIterator implements Iterator<TweetMessage> {
+
+        private int duration;
+        private final GULongIDGenerator idGen;
+        private long startTime = 0;
+
+        public TweetMessageIterator(int duration, GULongIDGenerator idGen) {
+            this.duration = duration;
+            this.idGen = idGen;
+            this.startTime = System.currentTimeMillis();
+        }
+
+        @Override
+        public boolean hasNext() {
+            if (duration == 0) {
+                return true;
+            }
+            return System.currentTimeMillis() - startTime <= duration * 1000;
+        }
+
+        @Override
+        public TweetMessage next() {
+            TweetMessage msg = null;
+            getTwitterUser(null);
+            Message message = randMessageGen.getNextRandomMessage();
+            Point location = randLocationGen != null ? randLocationGen.getRandomPoint()
+                    : locationGenFromOpenStreetMapData.getNextPoint();
+            DateTime sendTime = randDateGen.getNextRandomDatetime();
+            int btreeExtraFieldKey = random.nextInt();
+            if (btreeExtraFieldKey == Integer.MIN_VALUE) {
+                btreeExtraFieldKey = Integer.MIN_VALUE + 1;
+            }
+            twMessage.reset(idGen.getNextULong(), twUser, location, sendTime, message.getReferredTopics(), message,
+                    btreeExtraFieldKey, DUMMY_SIZE_ADJUSTER);
+            msg = twMessage;
+            return msg;
+        }
+
+        @Override
+        public void remove() {
+            // TODO Auto-generated method stub
+        }
+
+        public void resetDuration(int duration) {
+            this.duration = duration;
+            startTime = System.currentTimeMillis();
+        }
+
+    }
+
+    public static class InitializationInfo {
+        public Date startDate = new Date(1, 1, 2005);
+        public Date endDate = new Date(8, 20, 2012);
+        public String[] lastNames = DataGenerator.lastNames;
+        public String[] firstNames = DataGenerator.firstNames;
+        public String[] vendors = DataGenerator.vendors;
+        public String[] jargon = DataGenerator.jargon;
+        public String[] org_list = DataGenerator.org_list;
+    }
+
+    public void initialize(InitializationInfo info, String openStreetMapFilePath, int locationSampleInterval) {
+        randDateGen = new RandomDateGenerator(info.startDate, info.endDate);
+        randNameGen = new RandomNameGenerator(info.firstNames, info.lastNames);
+        if (openStreetMapFilePath == null) {
+            randLocationGen = new RandomLocationGenerator(24, 49, 66, 98);
+            locationGenFromOpenStreetMapData = null;
+        } else {
+            locationGenFromOpenStreetMapData = new LocationGeneratorFromOpenStreetMapData();
+            locationGenFromOpenStreetMapData.intialize(openStreetMapFilePath, locationSampleInterval);
+            randLocationGen = null;
+        }
+        randMessageGen = new RandomMessageGenerator(info.vendors, info.jargon);
+    }
+
+    public void getTwitterUser(String usernameSuffix) {
+        String suggestedName = randNameGen.getRandomName();
+        String[] nameComponents = suggestedName.split(" ");
+        String screenName = nameComponents[0] + nameComponents[1] + randNameGen.getRandomNameSuffix();
+        String name = suggestedName;
+        if (usernameSuffix != null) {
+            name = name + usernameSuffix;
+        }
+        int numFriends = random.nextInt((100)); // draw from Zipfian
+        int statusesCount = random.nextInt(500); // draw from Zipfian
+        int followersCount = random.nextInt((200));
+        twUser.reset(screenName, numFriends, statusesCount, name, followersCount);
+    }
+
+    public static class RandomDateGenerator {
+
+        private final Date startDate;
+        private final Date endDate;
+        private final Random random = new Random();
+        private final int yearDifference;
+        private Date workingDate;
+        private Date recentDate;
+        private DateTime dateTime;
+
+        public RandomDateGenerator(Date startDate, Date endDate) {
+            this.startDate = startDate;
+            this.endDate = endDate;
+            this.yearDifference = endDate.getYear() - startDate.getYear() + 1;
+            this.workingDate = new Date();
+            this.recentDate = new Date();
+            this.dateTime = new DateTime();
+        }
+
+        public Date getStartDate() {
+            return startDate;
+        }
+
+        public Date getEndDate() {
+            return endDate;
+        }
+
+        public Date getNextRandomDate() {
+            int year = random.nextInt(yearDifference) + startDate.getYear();
+            int month;
+            int day;
+            if (year == endDate.getYear()) {
+                month = random.nextInt(endDate.getMonth()) + 1;
+                if (month == endDate.getMonth()) {
+                    day = random.nextInt(endDate.getDay()) + 1;
+                } else {
+                    day = random.nextInt(28) + 1;
+                }
+            } else {
+                month = random.nextInt(12) + 1;
+                day = random.nextInt(28) + 1;
+            }
+            workingDate.reset(month, day, year);
+            return workingDate;
+        }
+
+        public DateTime getNextRandomDatetime() {
+            Date randomDate = getNextRandomDate();
+            dateTime.reset(randomDate);
+            return dateTime;
+        }
+
+        public Date getNextRecentDate(Date date) {
+            int year = date.getYear()
+                    + (date.getYear() == endDate.getYear() ? 0 : random.nextInt(endDate.getYear() - date.getYear()));
+            int month = (year == endDate.getYear())
+                    ? date.getMonth() == endDate.getMonth() ? (endDate.getMonth())
+                            : (date.getMonth() + random.nextInt(endDate.getMonth() - date.getMonth()))
+                    : random.nextInt(12) + 1;
+
+            int day = (year == endDate.getYear())
+                    ? month == endDate.getMonth()
+                            ? date.getDay() == endDate.getDay() ? endDate.getDay()
+                                    : date.getDay() + random.nextInt(endDate.getDay() - date.getDay())
+                            : random.nextInt(28) + 1
+                    : random.nextInt(28) + 1;
+            recentDate.reset(month, day, year);
+            return recentDate;
+        }
+
+    }
+
+    public static class DateTime extends Date {
+
+        private String hour = "10";
+        private String min = "10";
+        private String sec = "00";
+
+        public DateTime(int month, int day, int year, String hour, String min, String sec) {
+            super(month, day, year);
+            this.hour = hour;
+            this.min = min;
+            this.sec = sec;
+        }
+
+        public DateTime() {
+        }
+
+        public void reset(int month, int day, int year, String hour, String min, String sec) {
+            super.setDay(month);
+            super.setDay(day);
+            super.setYear(year);
+            this.hour = hour;
+            this.min = min;
+            this.sec = sec;
+        }
+
+        public DateTime(Date date) {
+            super(date.getMonth(), date.getDay(), date.getYear());
+        }
+
+        public void reset(Date date) {
+            reset(date.getMonth(), date.getDay(), date.getYear());
+        }
+
+        public DateTime(Date date, int hour, int min, int sec) {
+            super(date.getMonth(), date.getDay(), date.getYear());
+            this.hour = (hour < 10) ? "0" : "" + hour;
+            this.min = (min < 10) ? "0" : "" + min;
+            this.sec = (sec < 10) ? "0" : "" + sec;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder();
+            builder.append("datetime");
+            builder.append("(\"");
+            builder.append(super.getYear());
+            builder.append("-");
+            builder.append(super.getMonth() < 10 ? "0" + super.getMonth() : super.getMonth());
+            builder.append("-");
+            builder.append(super.getDay() < 10 ? "0" + super.getDay() : super.getDay());
+            builder.append("T");
+            builder.append(hour + ":" + min + ":" + sec);
+            builder.append("\")");
+            return builder.toString();
+        }
+    }
+
+    public static class Message {
+
+        private char[] message = new char[500];
+        private List<String> referredTopics;
+        private int length;
+
+        public Message(char[] m, List<String> referredTopics) {
+            System.arraycopy(m, 0, message, 0, m.length);
+            length = m.length;
+            this.referredTopics = referredTopics;
+        }
+
+        public Message() {
+            referredTopics = new ArrayList<String>();
+            length = 0;
+        }
+
+        public List<String> getReferredTopics() {
+            return referredTopics;
+        }
+
+        public void reset(char[] m, int offset, int length, List<String> referredTopics) {
+            System.arraycopy(m, offset, message, 0, length);
+            this.length = length;
+            this.referredTopics = referredTopics;
+        }
+
+        public int getLength() {
+            return length;
+        }
+
+        public char charAt(int index) {
+            return message[index];
+        }
+
+    }
+
+    public static class Point {
+
+        private float latitude;
+        private float longitude;
+
+        public float getLatitude() {
+            return latitude;
+        }
+
+        public float getLongitude() {
+            return longitude;
+        }
+
+        public Point(float latitude, float longitude) {
+            this.latitude = latitude;
+            this.longitude = longitude;
+        }
+
+        public void reset(float latitude, float longitude) {
+            this.latitude = latitude;
+            this.longitude = longitude;
+        }
+
+        public Point() {
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder();
+            builder.append("point(\"" + latitude + "," + longitude + "\")");
+            return builder.toString();
+        }
+    }
+
+    public static class RandomNameGenerator {
+
+        private String[] firstNames;
+        private String[] lastNames;
+
+        private final Random random = new Random();
+
+        private final String[] connectors = new String[] { "_", "#", "$", "@" };
+
+        public RandomNameGenerator(String[] firstNames, String[] lastNames) {
+            this.firstNames = firstNames;
+            this.lastNames = lastNames;
+        }
+
+        public String getRandomName() {
+            String name;
+            name = getSuggestedName();
+            return name;
+
+        }
+
+        private String getSuggestedName() {
+            int firstNameIndex = random.nextInt(firstNames.length);
+            int lastNameIndex = random.nextInt(lastNames.length);
+            String suggestedName = firstNames[firstNameIndex] + " " + lastNames[lastNameIndex];
+            return suggestedName;
+        }
+
+        public String getRandomNameSuffix() {
+            return connectors[random.nextInt(connectors.length)] + random.nextInt(1000);
+        }
+    }
+
+    public static class RandomMessageGenerator {
+
+        private final MessageTemplate messageTemplate;
+
+        public RandomMessageGenerator(String[] vendors, String[] jargon) {
+            List<String> vendorList = new ArrayList<String>();
+            for (String v : vendors) {
+                vendorList.add(v);
+            }
+            List<String> jargonList = new ArrayList<String>();
+            for (String j : jargon) {
+                jargonList.add(j);
+            }
+            this.messageTemplate = new MessageTemplate(vendorList, jargonList);
+        }
+
+        public Message getNextRandomMessage() {
+            return messageTemplate.getNextMessage();
+        }
+    }
+
+    public static class AbstractMessageTemplate {
+
+        protected final Random random = new Random();
+
+        protected String[] positiveVerbs = new String[] { "like", "love" };
+        protected String[] negativeVerbs = new String[] { "dislike", "hate", "can't stand" };
+
+        protected String[] negativeAdjectives = new String[] { "horrible", "bad", "terrible", "OMG" };
+        protected String[] postiveAdjectives = new String[] { "good", "awesome", "amazing", "mind-blowing" };
+
+        protected String[] otherWords = new String[] { "the", "its" };
+    }
+
+    public static class MessageTemplate extends AbstractMessageTemplate {
+
+        private List<String> vendors;
+        private List<String> jargon;
+        private CharBuffer buffer;
+        private List<String> referredTopics;
+        private Message message = new Message();
+
+        public MessageTemplate(List<String> vendors, List<String> jargon) {
+            this.vendors = vendors;
+            this.jargon = jargon;
+            buffer = CharBuffer.allocate(2500);
+            referredTopics = new ArrayList<String>();
+        }
+
+        public Message getNextMessage() {
+            buffer.position(0);
+            buffer.limit(2500);
+            referredTopics.clear();
+            boolean isPositive = random.nextBoolean();
+            String[] verbArray = isPositive ? positiveVerbs : negativeVerbs;
+            String[] adjectiveArray = isPositive ? postiveAdjectives : negativeAdjectives;
+            String verb = verbArray[random.nextInt(verbArray.length)];
+            String adjective = adjectiveArray[random.nextInt(adjectiveArray.length)];
+
+            buffer.put(" ");
+            buffer.put(verb);
+            buffer.put(" ");
+            String vendor = vendors.get(random.nextInt(vendors.size()));
+            referredTopics.add(vendor);
+            buffer.append(vendor);
+            buffer.append(" ");
+            buffer.append(otherWords[random.nextInt(otherWords.length)]);
+            buffer.append(" ");
+            String jargonTerm = jargon.get(random.nextInt(jargon.size()));
+            referredTopics.add(jargonTerm);
+            buffer.append(jargonTerm);
+            buffer.append(" is ");
+            buffer.append(adjective);
+            if (random.nextBoolean()) {
+                buffer.append(isPositive ? ":)" : ":(");
+            }
+
+            buffer.flip();
+            message.reset(buffer.array(), 0, buffer.limit(), referredTopics);
+            return message;
+        }
+    }
+
+    public static class RandomUtil {
+
+        public static Random random = new Random();
+
+        public static int[] getKFromN(int k, int n) {
+            int[] result = new int[k];
+            int cnt = 0;
+            HashSet<Integer> values = new HashSet<Integer>();
+            while (cnt < k) {
+                int val = random.nextInt(n + 1);
+                if (values.contains(val)) {
+                    continue;
+                }
+
+                result[cnt++] = val;
+                values.add(val);
+            }
+            return result;
+        }
+    }
+
+    public static class RandomLocationGenerator {
+
+        private Random random = new Random();
+
+        private final int beginLat;
+        private final int endLat;
+        private final int beginLong;
+        private final int endLong;
+
+        private Point point;
+
+        public RandomLocationGenerator(int beginLat, int endLat, int beginLong, int endLong) {
+            this.beginLat = beginLat;
+            this.endLat = endLat;
+            this.beginLong = beginLong;
+            this.endLong = endLong;
+            this.point = new Point();
+        }
+
+        public Point getRandomPoint() {
+            int latMajor = beginLat + random.nextInt(endLat - beginLat);
+            int latMinor = random.nextInt(100);
+            float latitude = latMajor + ((float) latMinor) / 100;
+
+            int longMajor = beginLong + random.nextInt(endLong - beginLong);
+            int longMinor = random.nextInt(100);
+            float longitude = longMajor + ((float) longMinor) / 100;
+
+            point.reset(latitude, longitude);
+            return point;
+        }
+
+    }
+
+    public static class LocationGeneratorFromOpenStreetMapData {
+        /**
+         * the source of gps data:
+         * https://blog.openstreetmap.org/2012/04/01/bulk-gps-point-data/
+         */
+        private String openStreetMapFilePath;
+        private long sampleInterval;
+        private long lineCount = 0;
+        private BufferedReader br;
+        private String line;
+        private String strPoints[] = null;
+        private StringBuilder sb = new StringBuilder();
+        private Point point = new Point();
+        private float[] floatPoint = new float[2];
+
+        public void intialize(String openStreetMapFilePath, int sampleInterval) {
+            this.openStreetMapFilePath = openStreetMapFilePath;
+            this.sampleInterval = sampleInterval;
+            try {
+                br = new BufferedReader(new FileReader(openStreetMapFilePath));
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+                throw new IllegalStateException(e);
+            }
+        }
+
+        public Point getNextPoint() {
+            try {
+                while (true) {
+                    if ((line = br.readLine()) == null) {
+                        br = new BufferedReader(new FileReader(openStreetMapFilePath));
+                        line = br.readLine(); //can't be null
+                    }
+                    if (lineCount++ % sampleInterval != 0) {
+                        continue;
+                    }
+                    sb.setLength(0);
+                    strPoints = line.split(",");
+                    if (strPoints.length != 2) {
+                        //ignore invalid point
+                        continue;
+                    } else {
+                        break;
+                    }
+                }
+                if (line == null) {
+                    //roll over the data from the same file.
+                    br.close();
+                    br = null;
+                    lineCount = 0;
+                    br = new BufferedReader(new FileReader(openStreetMapFilePath));
+                    while ((line = br.readLine()) != null) {
+                        if (lineCount++ % sampleInterval != 0) {
+                            continue;
+                        }
+                        sb.setLength(0);
+                        strPoints = line.split(",");
+                        if (strPoints.length != 2) {
+                            //ignore invalid point
+                            continue;
+                        } else {
+                            break;
+                        }
+                    }
+                }
+                floatPoint[0] = Float.parseFloat(strPoints[0]) / 10000000; //latitude (y value)
+                floatPoint[1] = Float.parseFloat(strPoints[1]) / 10000000; //longitude (x value)
+                point.reset(floatPoint[1], floatPoint[0]);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new IllegalStateException(e);
+            }
+            return point;
+        }
+
+        @Override
+        public void finalize() {
+            if (br != null) {
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    throw new IllegalStateException(e);
+                }
+            }
+        }
+    }
+
+    public static class TweetMessage {
+
+        private static int NUM_BTREE_EXTRA_FIELDS = 8;
+
+        private long tweetid;
+        private TwitterUser user;
+        private Point senderLocation;
+        private DateTime sendTime;
+        private List<String> referredTopics;
+        private Message messageText;
+        private int[] btreeExtraFields;
+        private String dummySizeAdjuster;
+
+        public TweetMessage() {
+            this.btreeExtraFields = new int[NUM_BTREE_EXTRA_FIELDS];
+        }
+
+        public TweetMessage(long tweetid, TwitterUser user, Point senderLocation, DateTime sendTime,
+                List<String> referredTopics, Message messageText, int btreeExtraField, String dummySizeAdjuster) {
+            this.tweetid = tweetid;
+            this.user = user;
+            this.senderLocation = senderLocation;
+            this.sendTime = sendTime;
+            this.referredTopics = referredTopics;
+            this.messageText = messageText;
+            this.btreeExtraFields = new int[NUM_BTREE_EXTRA_FIELDS];
+            setBtreeExtraFields(btreeExtraField);
+            this.dummySizeAdjuster = dummySizeAdjuster;
+        }
+
+        private void setBtreeExtraFields(int fVal) {
+            for (int i = 0; i < btreeExtraFields.length; ++i) {
+                btreeExtraFields[i] = fVal;
+            }
+        }
+
+        public void reset(long tweetid, TwitterUser user, Point senderLocation, DateTime sendTime,
+                List<String> referredTopics, Message messageText, int btreeExtraField, String dummySizeAdjuster) {
+            this.tweetid = tweetid;
+            this.user = user;
+            this.senderLocation = senderLocation;
+            this.sendTime = sendTime;
+            this.referredTopics = referredTopics;
+            this.messageText = messageText;
+            setBtreeExtraFields(btreeExtraField);
+            this.dummySizeAdjuster = dummySizeAdjuster;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder();
+            builder.append("{");
+            builder.append("\"tweetid\":");
+            builder.append("int64(\"" + tweetid + "\")");
+            builder.append(",");
+            builder.append("\"user\":");
+            builder.append(user);
+            builder.append(",");
+            builder.append("\"sender-location\":");
+            builder.append(senderLocation);
+            builder.append(",");
+            builder.append("\"send-time\":");
+            builder.append(sendTime);
+            builder.append(",");
+            builder.append("\"referred-topics\":");
+            builder.append("{{");
+            for (String topic : referredTopics) {
+                builder.append("\"" + topic + "\"");
+                builder.append(",");
+            }
+            if (referredTopics.size() > 0) {
+                builder.deleteCharAt(builder.lastIndexOf(","));
+            }
+            builder.append("}}");
+            builder.append(",");
+            builder.append("\"message-text\":");
+            builder.append("\"");
+            for (int i = 0; i < messageText.getLength(); i++) {
+                builder.append(messageText.charAt(i));
+            }
+            builder.append("\"");
+            builder.append(",");
+            for (int i = 0; i < btreeExtraFields.length; ++i) {
+                builder.append("\"btree-extra-field" + (i + 1) + "\":");
+                builder.append(btreeExtraFields[i]);
+                if (i != btreeExtraFields.length - 1) {
+                    builder.append(",");
+                }
+            }
+            builder.append(",");
+            builder.append("\"dummy-size-adjuster\":");
+            builder.append("\"");
+            builder.append(dummySizeAdjuster);
+            builder.append("\"");
+            builder.append("}");
+            return new String(builder);
+        }
+
+        public long getTweetid() {
+            return tweetid;
+        }
+
+        public void setTweetid(long tweetid) {
+            this.tweetid = tweetid;
+        }
+
+        public TwitterUser getUser() {
+            return user;
+        }
+
+        public void setUser(TwitterUser user) {
+            this.user = user;
+        }
+
+        public Point getSenderLocation() {
+            return senderLocation;
+        }
+
+        public void setSenderLocation(Point senderLocation) {
+            this.senderLocation = senderLocation;
+        }
+
+        public DateTime getSendTime() {
+            return sendTime;
+        }
+
+        public void setSendTime(DateTime sendTime) {
+            this.sendTime = sendTime;
+        }
+
+        public List<String> getReferredTopics() {
+            return referredTopics;
+        }
+
+        public void setReferredTopics(List<String> referredTopics) {
+            this.referredTopics = referredTopics;
+        }
+
+        public Message getMessageText() {
+            return messageText;
+        }
+
+        public void setMessageText(Message messageText) {
+            this.messageText = messageText;
+        }
+
+    }
+
+    public static class TwitterUser {
+
+        private String screenName;
+        private String lang = "en";
+        private int friendsCount;
+        private int statusesCount;
+        private String name;
+        private int followersCount;
+
+        public TwitterUser() {
+
+        }
+
+        public TwitterUser(String screenName, int friendsCount, int statusesCount, String name, int followersCount) {
+            this.screenName = screenName;
+            this.friendsCount = friendsCount;
+            this.statusesCount = statusesCount;
+            this.name = name;
+            this.followersCount = followersCount;
+        }
+
+        public void reset(String screenName, int friendsCount, int statusesCount, String name, int followersCount) {
+            this.screenName = screenName;
+            this.friendsCount = friendsCount;
+            this.statusesCount = statusesCount;
+            this.name = name;
+            this.followersCount = followersCount;
+        }
+
+        public String getScreenName() {
+            return screenName;
+        }
+
+        public int getFriendsCount() {
+            return friendsCount;
+        }
+
+        public int getStatusesCount() {
+            return statusesCount;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public int getFollowersCount() {
+            return followersCount;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder();
+            builder.append("{");
+            builder.append("\"screen-name\":" + "\"" + screenName + "\"");
+            builder.append(",");
+            builder.append("\"lang\":" + "\"" + lang + "\"");
+            builder.append(",");
+            builder.append("\"friends_count\":" + friendsCount);
+            builder.append(",");
+            builder.append("\"statuses_count\":" + statusesCount);
+            builder.append(",");
+            builder.append("\"name\":" + "\"" + name + "\"");
+            builder.append(",");
+            builder.append("\"followers_count\":" + followersCount);
+            builder.append("}");
+            return builder.toString();
+        }
+
+    }
+
+    public static class Date {
+
+        private int day;
+        private int month;
+        private int year;
+
+        public Date(int month, int day, int year) {
+            this.month = month;
+            this.day = day;
+            this.year = year;
+        }
+
+        public void reset(int month, int day, int year) {
+            this.month = month;
+            this.day = day;
+            this.year = year;
+        }
+
+        public int getDay() {
+            return day;
+        }
+
+        public int getMonth() {
+            return month;
+        }
+
+        public int getYear() {
+            return year;
+        }
+
+        public Date() {
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder();
+            builder.append("date");
+            builder.append("(\"");
+            builder.append(year);
+            builder.append("-");
+            builder.append(month < 10 ? "0" + month : "" + month);
+            builder.append("-");
+            builder.append(day < 10 ? "0" + day : "" + day);
+            builder.append("\")");
+            return builder.toString();
+        }
+
+        public void setDay(int day) {
+            this.day = day;
+        }
+
+        public void setMonth(int month) {
+            this.month = month;
+        }
+
+        public void setYear(int year) {
+            this.year = year;
+        }
+    }
+
+    public static String[] lastNames = { "Hoopengarner", "Harrow", "Gardner", "Blyant", "Best", "Buttermore", "Gronko",
+            "Mayers", "Countryman", "Neely", "Ruhl", "Taggart", "Bash", "Cason", "Hil", "Zalack", "Mingle", "Carr",
+            "Rohtin", "Wardle", "Pullman", "Wire", "Kellogg", "Hiles", "Keppel", "Bratton", "Sutton", "Wickes",
+            "Muller", "Friedline", "Llora", "Elizabeth", "Anderson", "Gaskins", "Rifler", "Vinsant", "Stanfield",
+            "Black", "Guest", "Hujsak", "Carter", "Weidemann", "Hays", "Patton", "Hayhurst", "Paynter", "Cressman",
+            "Fiddler", "Evans", "Sherlock", "Woodworth", "Jackson", "Bloise", "Schneider", "Ring", "Kepplinger",
+            "James", "Moon", "Bennett", "Bashline", "Ryals", "Zeal", "Christman", "Milliron", "Nash", "Ewing", "Camp",
+            "Mason", "Richardson", "Bowchiew", "Hahn", "Wilson", "Wood", "Toyley", "Williamson", "Lafortune", "Errett",
+            "Saltser", "Hirleman", "Brindle", "Newbiggin", "Ulery", "Lambert", "Shick", "Kuster", "Moore", "Finck",
+            "Powell", "Jolce", "Townsend", "Sauter", "Cowher", "Wolfe", "Cavalet", "Porter", "Laborde", "Ballou",
+            "Murray", "Stoddard", "Pycroft", "Milne", "King", "Todd", "Staymates", "Hall", "Romanoff", "Keilbach",
+            "Sandford", "Hamilton", "Fye", "Kline", "Weeks", "Mcelroy", "Mccullough", "Bryant", "Hill", "Moore",
+            "Ledgerwood", "Prevatt", "Eckert", "Read", "Hastings", "Doverspike", "Allshouse", "Bryan", "Mccallum",
+            "Lombardi", "Mckendrick", "Cattley", "Barkley", "Steiner", "Finlay", "Priebe", "Armitage", "Hall", "Elder",
+            "Erskine", "Hatcher", "Walker", "Pearsall", "Dunkle", "Haile", "Adams", "Miller", "Newbern", "Basinger",
+            "Fuhrer", "Brinigh", "Mench", "Blackburn", "Bastion", "Mccune", "Bridger", "Hynes", "Quinn", "Courtney",
+            "Geddinge", "Field", "Seelig", "Cable", "Earhart", "Harshman", "Roby", "Beals", "Berry", "Reed", "Hector",
+            "Pittman", "Haverrman", "Kalp", "Briner", "Joghs", "Cowart", "Close", "Wynne", "Harden", "Weldy",
+            "Stephenson", "Hildyard", "Moberly", "Wells", "Mackendoerfer", "Fisher", "Oppie", "Oneal", "Churchill",
+            "Keister", "Alice", "Tavoularis", "Fisher", "Hair", "Burns", "Veith", "Wile", "Fuller", "Fields", "Clark",
+            "Randolph", "Stone", "Mcclymonds", "Holtzer", "Donkin", "Wilkinson", "Rosensteel", "Albright", "Stahl",
+            "Fox", "Kadel", "Houser", "Hanseu", "Henderson", "Davis", "Bicknell", "Swain", "Mercer", "Holdeman",
+            "Enderly", "Caesar", "Margaret", "Munshower", "Elless", "Lucy", "Feufer", "Schofield", "Graham",
+            "Blatenberger", "Benford", "Akers", "Campbell", "Ann", "Sadley", "Ling", "Gongaware", "Schmidt", "Endsley",
+            "Groah", "Flanders", "Reichard", "Lowstetter", "Sandblom", "Griffis", "Basmanoff", "Coveney", "Hawker",
+            "Archibald", "Hutton", "Barnes", "Diegel", "Raybould", "Focell", "Breitenstein", "Murray", "Chauvin",
+            "Busk", "Pheleps", "Teagarden", "Northey", "Baumgartner", "Fleming", "Harris", "Parkinson", "Carpenter",
+            "Whirlow", "Bonner", "Wortman", "Rogers", "Scott", "Lowe", "Mckee", "Huston", "Bullard", "Throckmorton",
+            "Rummel", "Mathews", "Dull", "Saline", "Tue", "Woolery", "Lalty", "Schrader", "Ramsey", "Eisenmann",
+            "Philbrick", "Sybilla", "Wallace", "Fonblanque", "Paul", "Orbell", "Higgens", "Casteel", "Franks", "Demuth",
+            "Eisenman", "Hay", "Robinson", "Fischer", "Hincken", "Wylie", "Leichter", "Bousum", "Littlefield",
+            "Mcdonald", "Greif", "Rhodes", "Wall", "Steele", "Baldwin", "Smith", "Stewart", "Schere", "Mary", "Aultman",
+            "Emrick", "Guess", "Mitchell", "Painter", "Aft", "Hasely", "Weldi", "Loewentsein", "Poorbaugh", "Kepple",
+            "Noton", "Judge", "Jackson", "Style", "Adcock", "Diller", "Marriman", "Johnston", "Children", "Monahan",
+            "Ehret", "Shaw", "Congdon", "Pinney", "Millard", "Crissman", "Tanner", "Rose", "Knisely", "Cypret",
+            "Sommer", "Poehl", "Hardie", "Bender", "Overholt", "Gottwine", "Beach", "Leslie", "Trevithick", "Langston",
+            "Magor", "Shotts", "Howe", "Hunter", "Cross", "Kistler", "Dealtry", "Christner", "Pennington", "Thorley",
+            "Eckhardstein", "Van", "Stroh", "Stough", "Stall", "Beedell", "Shea", "Garland", "Mays", "Pritchard",
+            "Frankenberger", "Rowley", "Lane", "Baum", "Alliman", "Park", "Jardine", "Butler", "Cherry", "Kooser",
+            "Baxter", "Billimek", "Downing", "Hurst", "Wood", "Baird", "Watkins", "Edwards", "Kemerer", "Harding",
+            "Owens", "Eiford", "Keener", "Garneis", "Fiscina", "Mang", "Draudy", "Mills", "Gibson", "Reese", "Todd",
+            "Ramos", "Levett", "Wilks", "Ward", "Mosser", "Dunlap", "Kifer", "Christopher", "Ashbaugh", "Wynter",
+            "Rawls", "Cribbs", "Haynes", "Thigpen", "Schreckengost", "Bishop", "Linton", "Chapman", "James", "Jerome",
+            "Hook", "Omara", "Houston", "Maclagan", "Sandys", "Pickering", "Blois", "Dickson", "Kemble", "Duncan",
+            "Woodward", "Southern", "Henley", "Treeby", "Cram", "Elsas", "Driggers", "Warrick", "Overstreet", "Hindman",
+            "Buck", "Sulyard", "Wentzel", "Swink", "Butt", "Schaeffer", "Hoffhants", "Bould", "Willcox", "Lotherington",
+            "Bagley", "Graff", "White", "Wheeler", "Sloan", "Rodacker", "Hanford", "Jowers", "Kunkle", "Cass", "Powers",
+            "Gilman", "Mcmichaels", "Hobbs", "Herndon", "Prescott", "Smail", "Mcdonald", "Biery", "Orner", "Richards",
+            "Mueller", "Isaman", "Bruxner", "Goodman", "Barth", "Turzanski", "Vorrasi", "Stainforth", "Nehling", "Rahl",
+            "Erschoff", "Greene", "Mckinnon", "Reade", "Smith", "Pery", "Roose", "Greenwood", "Weisgarber", "Curry",
+            "Holts", "Zadovsky", "Parrish", "Putnam", "Munson", "Mcindoe", "Nickolson", "Brooks", "Bollinger",
+            "Stroble", "Siegrist", "Fulton", "Tomey", "Zoucks", "Roberts", "Otis", "Clarke", "Easter", "Johnson",
+            "Fylbrigg", "Taylor", "Swartzbaugh", "Weinstein", "Gadow", "Sayre", "Marcotte", "Wise", "Atweeke", "Mcfall",
+            "Napier", "Eisenhart", "Canham", "Sealis", "Baughman", "Gertraht", "Losey", "Laurence", "Eva", "Pershing",
+            "Kern", "Pirl", "Rega", "Sanborn", "Kanaga", "Sanders", "Anderson", "Dickinson", "Osteen", "Gettemy",
+            "Crom", "Snyder", "Reed", "Laurenzi", "Riggle", "Tillson", "Fowler", "Raub", "Jenner", "Koepple", "Soames",
+            "Goldvogel", "Dimsdale", "Zimmer", "Giesen", "Baker", "Beail", "Mortland", "Bard", "Sanner", "Knopsnider",
+            "Jenkins", "Bailey", "Werner", "Barrett", "Faust", "Agg", "Tomlinson", "Williams", "Little", "Greenawalt",
+            "Wells", "Wilkins", "Gisiko", "Bauerle", "Harrold", "Prechtl", "Polson", "Faast", "Winton", "Garneys",
+            "Peters", "Potter", "Porter", "Tennant", "Eve", "Dugger", "Jones", "Burch", "Cowper", "Whittier" };
+
+    public static String[] firstNames = { "Albert", "Jacquelin", "Dona", "Alia", "Mayme", "Genoveva", "Emma", "Lena",
+            "Melody", "Vilma", "Katelyn", "Jeremy", "Coral", "Leann", "Lita", "Gilda", "Kayla", "Alvina", "Maranda",
+            "Verlie", "Khadijah", "Karey", "Patrice", "Kallie", "Corey", "Mollie", "Daisy", "Melanie", "Sarita",
+            "Nichole", "Pricilla", "Terresa", "Berneice", "Arianne", "Brianne", "Lavinia", "Ulrike", "Lesha", "Adell",
+            "Ardelle", "Marisha", "Laquita", "Karyl", "Maryjane", "Kendall", "Isobel", "Raeann", "Heike", "Barbera",
+            "Norman", "Yasmine", "Nevada", "Mariam", "Edith", "Eugena", "Lovie", "Maren", "Bennie", "Lennie", "Tamera",
+            "Crystal", "Randi", "Anamaria", "Chantal", "Jesenia", "Avis", "Shela", "Randy", "Laurena", "Sharron",
+            "Christiane", "Lorie", "Mario", "Elizabeth", "Reina", "Adria", "Lakisha", "Brittni", "Azzie", "Dori",
+            "Shaneka", "Asuncion", "Katheryn", "Laurice", "Sharita", "Krystal", "Reva", "Inger", "Alpha", "Makeda",
+            "Anabel", "Loni", "Tiara", "Meda", "Latashia", "Leola", "Chin", "Daisey", "Ivory", "Amalia", "Logan",
+            "Tyler", "Kyong", "Carolann", "Maryetta", "Eufemia", "Anya", "Doreatha", "Lorna", "Rutha", "Ehtel",
+            "Debbie", "Chassidy", "Sang", "Christa", "Lottie", "Chun", "Karine", "Peggie", "Amina", "Melany", "Alayna",
+            "Scott", "Romana", "Naomi", "Christiana", "Salena", "Taunya", "Mitsue", "Regina", "Chelsie", "Charity",
+            "Dacia", "Aletha", "Latosha", "Lia", "Tamica", "Chery", "Bianca", "Shu", "Georgianne", "Myriam", "Austin",
+            "Wan", "Mallory", "Jana", "Georgie", "Jenell", "Kori", "Vicki", "Delfina", "June", "Mellisa", "Catherina",
+            "Claudie", "Tynisha", "Dayle", "Enriqueta", "Belen", "Pia", "Sarai", "Rosy", "Renay", "Kacie", "Frieda",
+            "Cayla", "Elissa", "Claribel", "Sabina", "Mackenzie", "Raina", "Cira", "Mitzie", "Aubrey", "Serafina",
+            "Maria", "Katharine", "Esperanza", "Sung", "Daria", "Billye", "Stefanie", "Kasha", "Holly", "Suzanne",
+            "Inga", "Flora", "Andria", "Genevie", "Eladia", "Janet", "Erline", "Renna", "Georgeanna", "Delorse",
+            "Elnora", "Rudy", "Rima", "Leanora", "Letisha", "Love", "Alverta", "Pinkie", "Domonique", "Jeannie", "Jose",
+            "Jacqueline", "Tara", "Lily", "Erna", "Tennille", "Galina", "Tamala", "Kirby", "Nichelle", "Myesha",
+            "Farah", "Santa", "Ludie", "Kenia", "Yee", "Micheline", "Maryann", "Elaina", "Ethelyn", "Emmaline",
+            "Shanell", "Marina", "Nila", "Alane", "Shakira", "Dorris", "Belinda", "Elois", "Barbie", "Carita", "Gisela",
+            "Lura", "Fransisca", "Helga", "Peg", "Leonarda", "Earlie", "Deetta", "Jacquetta", "Blossom", "Kayleigh",
+            "Deloras", "Keshia", "Christinia", "Dulce", "Bernie", "Sheba", "Lashanda", "Tula", "Claretta", "Kary",
+            "Jeanette", "Lupita", "Lenora", "Hisako", "Sherise", "Glynda", "Adela", "Chia", "Sudie", "Mindy", "Caroyln",
+            "Lindsey", "Xiomara", "Mercedes", "Onie", "Loan", "Alexis", "Tommie", "Donette", "Monica", "Soo",
+            "Camellia", "Lavera", "Valery", "Ariana", "Sophia", "Loris", "Ginette", "Marielle", "Tari", "Julissa",
+            "Alesia", "Suzanna", "Emelda", "Erin", "Ladawn", "Sherilyn", "Candice", "Nereida", "Fairy", "Carl", "Joel",
+            "Marilee", "Gracia", "Cordie", "So", "Shanita", "Drew", "Cassie", "Sherie", "Marget", "Norma", "Delois",
+            "Debera", "Chanelle", "Catarina", "Aracely", "Carlene", "Tricia", "Aleen", "Katharina", "Marguerita",
+            "Guadalupe", "Margorie", "Mandie", "Kathe", "Chong", "Sage", "Faith", "Maryrose", "Stephany", "Ivy",
+            "Pauline", "Susie", "Cristen", "Jenifer", "Annette", "Debi", "Karmen", "Luci", "Shayla", "Hope", "Ocie",
+            "Sharie", "Tami", "Breana", "Kerry", "Rubye", "Lashay", "Sondra", "Katrice", "Brunilda", "Cortney", "Yan",
+            "Zenobia", "Penni", "Addie", "Lavona", "Noel", "Anika", "Herlinda", "Valencia", "Bunny", "Tory", "Victoria",
+            "Carrie", "Mikaela", "Wilhelmina", "Chung", "Hortencia", "Gerda", "Wen", "Ilana", "Sibyl", "Candida",
+            "Victorina", "Chantell", "Casie", "Emeline", "Dominica", "Cecila", "Delora", "Miesha", "Nova", "Sally",
+            "Ronald", "Charlette", "Francisca", "Mina", "Jenna", "Loraine", "Felisa", "Lulu", "Page", "Lyda", "Babara",
+            "Flor", "Walter", "Chan", "Sherika", "Kala", "Luna", "Vada", "Syreeta", "Slyvia", "Karin", "Renata",
+            "Robbi", "Glenda", "Delsie", "Lizzie", "Genia", "Caitlin", "Bebe", "Cory", "Sam", "Leslee", "Elva", "Caren",
+            "Kasie", "Leticia", "Shannan", "Vickey", "Sandie", "Kyle", "Chang", "Terrilyn", "Sandra", "Elida",
+            "Marketta", "Elsy", "Tu", "Carman", "Ashlie", "Vernia", "Albertine", "Vivian", "Elba", "Bong", "Margy",
+            "Janetta", "Xiao", "Teofila", "Danyel", "Nickole", "Aleisha", "Tera", "Cleotilde", "Dara", "Paulita",
+            "Isela", "Maricela", "Rozella", "Marivel", "Aurora", "Melissa", "Carylon", "Delinda", "Marvella",
+            "Candelaria", "Deidre", "Tawanna", "Myrtie", "Milagro", "Emilie", "Coretta", "Ivette", "Suzann", "Ammie",
+            "Lucina", "Lory", "Tena", "Eleanor", "Cherlyn", "Tiana", "Brianna", "Myra", "Flo", "Carisa", "Kandi",
+            "Erlinda", "Jacqulyn", "Fermina", "Riva", "Palmira", "Lindsay", "Annmarie", "Tamiko", "Carline", "Amelia",
+            "Quiana", "Lashawna", "Veola", "Belva", "Marsha", "Verlene", "Alex", "Leisha", "Camila", "Mirtha", "Melva",
+            "Lina", "Arla", "Cythia", "Towanda", "Aracelis", "Tasia", "Aurore", "Trinity", "Bernadine", "Farrah",
+            "Deneen", "Ines", "Betty", "Lorretta", "Dorethea", "Hertha", "Rochelle", "Juli", "Shenika", "Yung", "Lavon",
+            "Deeanna", "Nakia", "Lynnette", "Dinorah", "Nery", "Elene", "Carolee", "Mira", "Franchesca", "Lavonda",
+            "Leida", "Paulette", "Dorine", "Allegra", "Keva", "Jeffrey", "Bernardina", "Maryln", "Yoko", "Faviola",
+            "Jayne", "Lucilla", "Charita", "Ewa", "Ella", "Maggie", "Ivey", "Bettie", "Jerri", "Marni", "Bibi",
+            "Sabrina", "Sarah", "Marleen", "Katherin", "Remona", "Jamika", "Antonina", "Oliva", "Lajuana", "Fonda",
+            "Sigrid", "Yael", "Billi", "Verona", "Arminda", "Mirna", "Tesha", "Katheleen", "Bonita", "Kamilah",
+            "Patrica", "Julio", "Shaina", "Mellie", "Denyse", "Deandrea", "Alena", "Meg", "Kizzie", "Krissy", "Karly",
+            "Alleen", "Yahaira", "Lucie", "Karena", "Elaine", "Eloise", "Buena", "Marianela", "Renee", "Nan",
+            "Carolynn", "Windy", "Avril", "Jane", "Vida", "Thea", "Marvel", "Rosaline", "Tifany", "Robena", "Azucena",
+            "Carlota", "Mindi", "Andera", "Jenny", "Courtney", "Lyndsey", "Willette", "Kristie", "Shaniqua", "Tabatha",
+            "Ngoc", "Una", "Marlena", "Louetta", "Vernie", "Brandy", "Jacquelyne", "Jenelle", "Elna", "Erminia", "Ida",
+            "Audie", "Louis", "Marisol", "Shawana", "Harriette", "Karol", "Kitty", "Esmeralda", "Vivienne", "Eloisa",
+            "Iris", "Jeanice", "Cammie", "Jacinda", "Shena", "Floy", "Theda", "Lourdes", "Jayna", "Marg", "Kati",
+            "Tanna", "Rosalyn", "Maxima", "Soon", "Angelika", "Shonna", "Merle", "Kassandra", "Deedee", "Heidi",
+            "Marti", "Renae", "Arleen", "Alfredia", "Jewell", "Carley", "Pennie", "Corina", "Tonisha", "Natividad",
+            "Lilliana", "Darcie", "Shawna", "Angel", "Piedad", "Josefa", "Rebbeca", "Natacha", "Nenita", "Petrina",
+            "Carmon", "Chasidy", "Temika", "Dennise", "Renetta", "Augusta", "Shirlee", "Valeri", "Casimira", "Janay",
+            "Berniece", "Deborah", "Yaeko", "Mimi", "Digna", "Irish", "Cher", "Yong", "Lucila", "Jimmie", "Junko",
+            "Lezlie", "Waneta", "Sandee", "Marquita", "Eura", "Freeda", "Annabell", "Laree", "Jaye", "Wendy", "Toshia",
+            "Kylee", "Aleta", "Emiko", "Clorinda", "Sixta", "Audrea", "Juanita", "Birdie", "Reita", "Latanya", "Nia",
+            "Leora", "Laurine", "Krysten", "Jerrie", "Chantel", "Ira", "Sena", "Andre", "Jann", "Marla", "Precious",
+            "Katy", "Gabrielle", "Yvette", "Brook", "Shirlene", "Eldora", "Laura", "Milda", "Euna", "Jettie", "Debora",
+            "Lise", "Edythe", "Leandra", "Shandi", "Araceli", "Johanne", "Nieves", "Denese", "Carmelita", "Nohemi",
+            "Annice", "Natalie", "Yolande", "Jeffie", "Vashti", "Vickie", "Obdulia", "Youlanda", "Lupe", "Tomoko",
+            "Monserrate", "Domitila", "Etsuko", "Adrienne", "Lakesha", "Melissia", "Odessa", "Meagan", "Veronika",
+            "Jolyn", "Isabelle", "Leah", "Rhiannon", "Gianna", "Audra", "Sommer", "Renate", "Perla", "Thao", "Myong",
+            "Lavette", "Mark", "Emilia", "Ariane", "Karl", "Dorie", "Jacquie", "Mia", "Malka", "Shenita", "Tashina",
+            "Christine", "Cherri", "Roni", "Fran", "Mildred", "Sara", "Clarissa", "Fredia", "Elease", "Samuel",
+            "Earlene", "Vernita", "Mae", "Concha", "Renea", "Tamekia", "Hye", "Ingeborg", "Tessa", "Kelly", "Kristin",
+            "Tam", "Sacha", "Kanisha", "Jillian", "Tiffanie", "Ashlee", "Madelyn", "Donya", "Clementine", "Mickie",
+            "My", "Zena", "Terrie", "Samatha", "Gertie", "Tarra", "Natalia", "Sharlene", "Evie", "Shalon", "Rosalee",
+            "Numbers", "Jodi", "Hattie", "Naoma", "Valene", "Whitley", "Claude", "Alline", "Jeanne", "Camie",
+            "Maragret", "Viola", "Kris", "Marlo", "Arcelia", "Shari", "Jalisa", "Corrie", "Eleonor", "Angelyn", "Merry",
+            "Lauren", "Melita", "Gita", "Elenor", "Aurelia", "Janae", "Lyndia", "Margeret", "Shawanda", "Rolande",
+            "Shirl", "Madeleine", "Celinda", "Jaleesa", "Shemika", "Joye", "Tisa", "Trudie", "Kathrine", "Clarita",
+            "Dinah", "Georgia", "Antoinette", "Janis", "Suzette", "Sherri", "Herta", "Arie", "Hedy", "Cassi", "Audrie",
+            "Caryl", "Jazmine", "Jessica", "Beverly", "Elizbeth", "Marylee", "Londa", "Fredericka", "Argelia", "Nana",
+            "Donnette", "Damaris", "Hailey", "Jamee", "Kathlene", "Glayds", "Lydia", "Apryl", "Verla", "Adam",
+            "Concepcion", "Zelda", "Shonta", "Vernice", "Detra", "Meghann", "Sherley", "Sheri", "Kiyoko", "Margarita",
+            "Adaline", "Mariela", "Velda", "Ailene", "Juliane", "Aiko", "Edyth", "Cecelia", "Shavon", "Florance",
+            "Madeline", "Rheba", "Deann", "Ignacia", "Odelia", "Heide", "Mica", "Jennette", "Maricruz", "Ouida",
+            "Darcy", "Laure", "Justina", "Amada", "Laine", "Cruz", "Sunny", "Francene", "Roxanna", "Nam", "Nancie",
+            "Deanna", "Letty", "Britni", "Kazuko", "Lacresha", "Simon", "Caleb", "Milton", "Colton", "Travis", "Miles",
+            "Jonathan", "Logan", "Rolf", "Emilio", "Roberto", "Marcus", "Tim", "Delmar", "Devon", "Kurt", "Edward",
+            "Jeffrey", "Elvis", "Alfonso", "Blair", "Wm", "Sheldon", "Leonel", "Michal", "Federico", "Jacques",
+            "Leslie", "Augustine", "Hugh", "Brant", "Hong", "Sal", "Modesto", "Curtis", "Jefferey", "Adam", "John",
+            "Glenn", "Vance", "Alejandro", "Refugio", "Lucio", "Demarcus", "Chang", "Huey", "Neville", "Preston",
+            "Bert", "Abram", "Foster", "Jamison", "Kirby", "Erich", "Manual", "Dustin", "Derrick", "Donnie", "Jospeh",
+            "Chris", "Josue", "Stevie", "Russ", "Stanley", "Nicolas", "Samuel", "Waldo", "Jake", "Max", "Ernest",
+            "Reinaldo", "Rene", "Gale", "Morris", "Nathan", "Maximo", "Courtney", "Theodore", "Octavio", "Otha",
+            "Delmer", "Graham", "Dean", "Lowell", "Myles", "Colby", "Boyd", "Adolph", "Jarrod", "Nick", "Mark",
+            "Clinton", "Kim", "Sonny", "Dalton", "Tyler", "Jody", "Orville", "Luther", "Rubin", "Hollis", "Rashad",
+            "Barton", "Vicente", "Ted", "Rick", "Carmine", "Clifton", "Gayle", "Christopher", "Jessie", "Bradley",
+            "Clay", "Theo", "Josh", "Mitchell", "Boyce", "Chung", "Eugenio", "August", "Norbert", "Sammie", "Jerry",
+            "Adan", "Edmundo", "Homer", "Hilton", "Tod", "Kirk", "Emmett", "Milan", "Quincy", "Jewell", "Herb", "Steve",
+            "Carmen", "Bobby", "Odis", "Daron", "Jeremy", "Carl", "Hunter", "Tuan", "Thurman", "Asa", "Brenton",
+            "Shane", "Donny", "Andreas", "Teddy", "Dario", "Cyril", "Hoyt", "Teodoro", "Vincenzo", "Hilario", "Daren",
+            "Agustin", "Marquis", "Ezekiel", "Brendan", "Johnson", "Alden", "Richie", "Granville", "Chad", "Joseph",
+            "Lamont", "Jordon", "Gilberto", "Chong", "Rosendo", "Eddy", "Rob", "Dewitt", "Andre", "Titus", "Russell",
+            "Rigoberto", "Dick", "Garland", "Gabriel", "Hank", "Darius", "Ignacio", "Lazaro", "Johnie", "Mauro",
+            "Edmund", "Trent", "Harris", "Osvaldo", "Marvin", "Judson", "Rodney", "Randall", "Renato", "Richard",
+            "Denny", "Jon", "Doyle", "Cristopher", "Wilson", "Christian", "Jamie", "Roland", "Ken", "Tad", "Romeo",
+            "Seth", "Quinton", "Byron", "Ruben", "Darrel", "Deandre", "Broderick", "Harold", "Ty", "Monroe", "Landon",
+            "Mohammed", "Angel", "Arlen", "Elias", "Andres", "Carlton", "Numbers", "Tony", "Thaddeus", "Issac", "Elmer",
+            "Antoine", "Ned", "Fermin", "Grover", "Benito", "Abdul", "Cortez", "Eric", "Maxwell", "Coy", "Gavin",
+            "Rich", "Andy", "Del", "Giovanni", "Major", "Efren", "Horacio", "Joaquin", "Charles", "Noah", "Deon",
+            "Pasquale", "Reed", "Fausto", "Jermaine", "Irvin", "Ray", "Tobias", "Carter", "Yong", "Jorge", "Brent",
+            "Daniel", "Zane", "Walker", "Thad", "Shaun", "Jaime", "Mckinley", "Bradford", "Nathanial", "Jerald",
+            "Aubrey", "Virgil", "Abel", "Philip", "Chester", "Chadwick", "Dominick", "Britt", "Emmitt", "Ferdinand",
+            "Julian", "Reid", "Santos", "Dwain", "Morgan", "James", "Marion", "Micheal", "Eddie", "Brett", "Stacy",
+            "Kerry", "Dale", "Nicholas", "Darrick", "Freeman", "Scott", "Newton", "Sherman", "Felton", "Cedrick",
+            "Winfred", "Brad", "Fredric", "Dewayne", "Virgilio", "Reggie", "Edgar", "Heriberto", "Shad", "Timmy",
+            "Javier", "Nestor", "Royal", "Lynn", "Irwin", "Ismael", "Jonas", "Wiley", "Austin", "Kieth", "Gonzalo",
+            "Paris", "Earnest", "Arron", "Jarred", "Todd", "Erik", "Maria", "Chauncey", "Neil", "Conrad", "Maurice",
+            "Roosevelt", "Jacob", "Sydney", "Lee", "Basil", "Louis", "Rodolfo", "Rodger", "Roman", "Corey", "Ambrose",
+            "Cristobal", "Sylvester", "Benton", "Franklin", "Marcelo", "Guillermo", "Toby", "Jeramy", "Donn", "Danny",
+            "Dwight", "Clifford", "Valentine", "Matt", "Jules", "Kareem", "Ronny", "Lonny", "Son", "Leopoldo", "Dannie",
+            "Gregg", "Dillon", "Orlando", "Weston", "Kermit", "Damian", "Abraham", "Walton", "Adrian", "Rudolf", "Will",
+            "Les", "Norberto", "Fred", "Tyrone", "Ariel", "Terry", "Emmanuel", "Anderson", "Elton", "Otis", "Derek",
+            "Frankie", "Gino", "Lavern", "Jarod", "Kenny", "Dane", "Keenan", "Bryant", "Eusebio", "Dorian", "Ali",
+            "Lucas", "Wilford", "Jeremiah", "Warner", "Woodrow", "Galen", "Bob", "Johnathon", "Amado", "Michel",
+            "Harry", "Zachery", "Taylor", "Booker", "Hershel", "Mohammad", "Darrell", "Kyle", "Stuart", "Marlin",
+            "Hyman", "Jeffery", "Sidney", "Merrill", "Roy", "Garrett", "Porter", "Kenton", "Giuseppe", "Terrance",
+            "Trey", "Felix", "Buster", "Von", "Jackie", "Linwood", "Darron", "Francisco", "Bernie", "Diego", "Brendon",
+            "Cody", "Marco", "Ahmed", "Antonio", "Vince", "Brooks", "Kendrick", "Ross", "Mohamed", "Jim", "Benny",
+            "Gerald", "Pablo", "Charlie", "Antony", "Werner", "Hipolito", "Minh", "Mel", "Derick", "Armand", "Fidel",
+            "Lewis", "Donnell", "Desmond", "Vaughn", "Guadalupe", "Keneth", "Rodrick", "Spencer", "Chas", "Gus",
+            "Harlan", "Wes", "Carmelo", "Jefferson", "Gerard", "Jarvis", "Haywood", "Hayden", "Sergio", "Gene",
+            "Edgardo", "Colin", "Horace", "Dominic", "Aldo", "Adolfo", "Juan", "Man", "Lenard", "Clement", "Everett",
+            "Hal", "Bryon", "Mason", "Emerson", "Earle", "Laurence", "Columbus", "Lamar", "Douglas", "Ian", "Fredrick",
+            "Marc", "Loren", "Wallace", "Randell", "Noble", "Ricardo", "Rory", "Lindsey", "Boris", "Bill", "Carlos",
+            "Domingo", "Grant", "Craig", "Ezra", "Matthew", "Van", "Rudy", "Danial", "Brock", "Maynard", "Vincent",
+            "Cole", "Damion", "Ellsworth", "Marcel", "Markus", "Rueben", "Tanner", "Reyes", "Hung", "Kennith",
+            "Lindsay", "Howard", "Ralph", "Jed", "Monte", "Garfield", "Avery", "Bernardo", "Malcolm", "Sterling",
+            "Ezequiel", "Kristofer", "Luciano", "Casey", "Rosario", "Ellis", "Quintin", "Trevor", "Miquel", "Jordan",
+            "Arthur", "Carson", "Tyron", "Grady", "Walter", "Jonathon", "Ricky", "Bennie", "Terrence", "Dion", "Dusty",
+            "Roderick", "Isaac", "Rodrigo", "Harrison", "Zack", "Dee", "Devin", "Rey", "Ulysses", "Clint", "Greg",
+            "Dino", "Frances", "Wade", "Franklyn", "Jude", "Bradly", "Salvador", "Rocky", "Weldon", "Lloyd", "Milford",
+            "Clarence", "Alec", "Allan", "Bobbie", "Oswaldo", "Wilfred", "Raleigh", "Shelby", "Willy", "Alphonso",
+            "Arnoldo", "Robbie", "Truman", "Nicky", "Quinn", "Damien", "Lacy", "Marcos", "Parker", "Burt", "Carroll",
+            "Denver", "Buck", "Dong", "Normand", "Billie", "Edwin", "Troy", "Arden", "Rusty", "Tommy", "Kenneth", "Leo",
+            "Claud", "Joel", "Kendall", "Dante", "Milo", "Cruz", "Lucien", "Ramon", "Jarrett", "Scottie", "Deshawn",
+            "Ronnie", "Pete", "Alonzo", "Whitney", "Stefan", "Sebastian", "Edmond", "Enrique", "Branden", "Leonard",
+            "Loyd", "Olin", "Ron", "Rhett", "Frederic", "Orval", "Tyrell", "Gail", "Eli", "Antonia", "Malcom", "Sandy",
+            "Stacey", "Nickolas", "Hosea", "Santo", "Oscar", "Fletcher", "Dave", "Patrick", "Dewey", "Bo", "Vito",
+            "Blaine", "Randy", "Robin", "Winston", "Sammy", "Edwardo", "Manuel", "Valentin", "Stanford", "Filiberto",
+            "Buddy", "Zachariah", "Johnnie", "Elbert", "Paul", "Isreal", "Jerrold", "Leif", "Owen", "Sung", "Junior",
+            "Raphael", "Josef", "Donte", "Allen", "Florencio", "Raymond", "Lauren", "Collin", "Eliseo", "Bruno",
+            "Martin", "Lyndon", "Kurtis", "Salvatore", "Erwin", "Michael", "Sean", "Davis", "Alberto", "King",
+            "Rolland", "Joe", "Tory", "Chase", "Dallas", "Vernon", "Beau", "Terrell", "Reynaldo", "Monty", "Jame",
+            "Dirk", "Florentino", "Reuben", "Saul", "Emory", "Esteban", "Michale", "Claudio", "Jacinto", "Kelley",
+            "Levi", "Andrea", "Lanny", "Wendell", "Elwood", "Joan", "Felipe", "Palmer", "Elmo", "Lawrence", "Hubert",
+            "Rudolph", "Duane", "Cordell", "Everette", "Mack", "Alan", "Efrain", "Trenton", "Bryan", "Tom", "Wilmer",
+            "Clyde", "Chance", "Lou", "Brain", "Justin", "Phil", "Jerrod", "George", "Kris", "Cyrus", "Emery", "Rickey",
+            "Lincoln", "Renaldo", "Mathew", "Luke", "Dwayne", "Alexis", "Jackson", "Gil", "Marty", "Burton", "Emil",
+            "Glen", "Willian", "Clemente", "Keven", "Barney", "Odell", "Reginald", "Aurelio", "Damon", "Ward",
+            "Gustavo", "Harley", "Peter", "Anibal", "Arlie", "Nigel", "Oren", "Zachary", "Scot", "Bud", "Wilbert",
+            "Bart", "Josiah", "Marlon", "Eldon", "Darryl", "Roger", "Anthony", "Omer", "Francis", "Patricia", "Moises",
+            "Chuck", "Waylon", "Hector", "Jamaal", "Cesar", "Julius", "Rex", "Norris", "Ollie", "Isaias", "Quentin",
+            "Graig", "Lyle", "Jeffry", "Karl", "Lester", "Danilo", "Mike", "Dylan", "Carlo", "Ryan", "Leon", "Percy",
+            "Lucius", "Jamel", "Lesley", "Joey", "Cornelius", "Rico", "Arnulfo", "Chet", "Margarito", "Ernie",
+            "Nathanael", "Amos", "Cleveland", "Luigi", "Alfonzo", "Phillip", "Clair", "Elroy", "Alva", "Hans", "Shon",
+            "Gary", "Jesus", "Cary", "Silas", "Keith", "Israel", "Willard", "Randolph", "Dan", "Adalberto", "Claude",
+            "Delbert", "Garry", "Mary", "Larry", "Riley", "Robt", "Darwin", "Barrett", "Steven", "Kelly", "Herschel",
+            "Darnell", "Scotty", "Armando", "Miguel", "Lawerence", "Wesley", "Garth", "Carol", "Micah", "Alvin",
+            "Billy", "Earl", "Pat", "Brady", "Cory", "Carey", "Bernard", "Jayson", "Nathaniel", "Gaylord", "Archie",
+            "Dorsey", "Erasmo", "Angelo", "Elisha", "Long", "Augustus", "Hobert", "Drew", "Stan", "Sherwood", "Lorenzo",
+            "Forrest", "Shawn", "Leigh", "Hiram", "Leonardo", "Gerry", "Myron", "Hugo", "Alvaro", "Leland", "Genaro",
+            "Jamey", "Stewart", "Elden", "Irving", "Olen", "Antone", "Freddy", "Lupe", "Joshua", "Gregory", "Andrew",
+            "Sang", "Wilbur", "Gerardo", "Merlin", "Williams", "Johnny", "Alex", "Tommie", "Jimmy", "Donovan", "Dexter",
+            "Gaston", "Tracy", "Jeff", "Stephen", "Berry", "Anton", "Darell", "Fritz", "Willis", "Noel", "Mariano",
+            "Crawford", "Zoey", "Alex", "Brianna", "Carlie", "Lloyd", "Cal", "Astor", "Randolf", "Magdalene",
+            "Trevelyan", "Terance", "Roy", "Kermit", "Harriett", "Crystal", "Laurinda", "Kiersten", "Phyllida", "Liz",
+            "Bettie", "Rena", "Colten", "Berenice", "Sindy", "Wilma", "Amos", "Candi", "Ritchie", "Dirk", "Kathlyn",
+            "Callista", "Anona", "Flossie", "Sterling", "Calista", "Regan", "Erica", "Jeana", "Keaton", "York", "Nolan",
+            "Daniel", "Benton", "Tommie", "Serenity", "Deanna", "Chas", "Heron", "Marlyn", "Xylia", "Tristin", "Lyndon",
+            "Andriana", "Madelaine", "Maddison", "Leila", "Chantelle", "Audrey", "Connor", "Daley", "Tracee", "Tilda",
+            "Eliot", "Merle", "Linwood", "Kathryn", "Silas", "Alvina", "Phinehas", "Janis", "Alvena", "Zubin",
+            "Gwendolen", "Caitlyn", "Bertram", "Hailee", "Idelle", "Homer", "Jannah", "Delbert", "Rhianna", "Cy",
+            "Jefferson", "Wayland", "Nona", "Tempest", "Reed", "Jenifer", "Ellery", "Nicolina", "Aldous", "Prince",
+            "Lexia", "Vinnie", "Doug", "Alberic", "Kayleen", "Woody", "Rosanne", "Ysabel", "Skyler", "Twyla", "Geordie",
+            "Leta", "Clive", "Aaron", "Scottie", "Celeste", "Chuck", "Erle", "Lallie", "Jaycob", "Ray", "Carrie",
+            "Laurita", "Noreen", "Meaghan", "Ulysses", "Andy", "Drogo", "Dina", "Yasmin", "Mya", "Luvenia", "Urban",
+            "Jacob", "Laetitia", "Sherry", "Love", "Michaela", "Deonne", "Summer", "Brendon", "Sheena", "Mason",
+            "Jayson", "Linden", "Salal", "Darrell", "Diana", "Hudson", "Lennon", "Isador", "Charley", "April", "Ralph",
+            "James", "Mina", "Jolyon", "Laurine", "Monna", "Carita", "Munro", "Elsdon", "Everette", "Radclyffe",
+            "Darrin", "Herbert", "Gawain", "Sheree", "Trudy", "Emmaline", "Kassandra", "Rebecca", "Basil", "Jen", "Don",
+            "Osborne", "Lilith", "Hannah", "Fox", "Rupert", "Paulene", "Darius", "Wally", "Baptist", "Sapphire", "Tia",
+            "Sondra", "Kylee", "Ashton", "Jepson", "Joetta", "Val", "Adela", "Zacharias", "Zola", "Marmaduke",
+            "Shannah", "Posie", "Oralie", "Brittany", "Ernesta", "Raymund", "Denzil", "Daren", "Roosevelt", "Nelson",
+            "Fortune", "Mariel", "Nick", "Jaden", "Upton", "Oz", "Margaux", "Precious", "Albert", "Bridger", "Jimmy",
+            "Nicola", "Rosalynne", "Keith", "Walt", "Della", "Joanna", "Xenia", "Esmeralda", "Major", "Simon", "Rexana",
+            "Stacy", "Calanthe", "Sherley", "Kaitlyn", "Graham", "Ramsey", "Abbey", "Madlyn", "Kelvin", "Bill", "Rue",
+            "Monica", "Caileigh", "Laraine", "Booker", "Jayna", "Greta", "Jervis", "Sherman", "Kendrick", "Tommy",
+            "Iris", "Geffrey", "Kaelea", "Kerr", "Garrick", "Jep", "Audley", "Nic", "Bronte", "Beulah", "Patricia",
+            "Jewell", "Deidra", "Cory", "Everett", "Harper", "Charity", "Godfrey", "Jaime", "Sinclair", "Talbot",
+            "Dayna", "Cooper", "Rosaline", "Jennie", "Eileen", "Latanya", "Corinna", "Roxie", "Caesar", "Charles",
+            "Pollie", "Lindsey", "Sorrel", "Dwight", "Jocelyn", "Weston", "Shyla", "Valorie", "Bessie", "Josh",
+            "Lessie", "Dayton", "Kathi", "Chasity", "Wilton", "Adam", "William", "Ash", "Angela", "Ivor", "Ria",
+            "Jazmine", "Hailey", "Jo", "Silvestra", "Ernie", "Clifford", "Levi", "Matilda", "Quincey", "Camilla",
+            "Delicia", "Phemie", "Laurena", "Bambi", "Lourdes", "Royston", "Chastity", "Lynwood", "Elle", "Brenda",
+            "Phoebe", "Timothy", "Raschelle", "Lilly", "Burt", "Rina", "Rodney", "Maris", "Jaron", "Wilf", "Harlan",
+            "Audra", "Vincent", "Elwyn", "Drew", "Wynter", "Ora", "Lissa", "Virgil", "Xavier", "Chad", "Ollie",
+            "Leyton", "Karolyn", "Skye", "Roni", "Gladys", "Dinah", "Penny", "August", "Osmund", "Whitaker", "Brande",
+            "Cornell", "Phil", "Zara", "Kilie", "Gavin", "Coty", "Randy", "Teri", "Keira", "Pru", "Clemency", "Kelcey",
+            "Nevil", "Poppy", "Gareth", "Christabel", "Bastian", "Wynonna", "Roselyn", "Goddard", "Collin", "Trace",
+            "Neal", "Effie", "Denys", "Virginia", "Richard", "Isiah", "Harrietta", "Gaylord", "Diamond", "Trudi",
+            "Elaine", "Jemmy", "Gage", "Annabel", "Quincy", "Syd", "Marianna", "Philomena", "Aubree", "Kathie", "Jacki",
+            "Kelley", "Bess", "Cecil", "Maryvonne", "Kassidy", "Anselm", "Dona", "Darby", "Jamison", "Daryl", "Darell",
+            "Teal", "Lennie", "Bartholomew", "Katie", "Maybelline", "Kimball", "Elvis", "Les", "Flick", "Harley",
+            "Beth", "Bidelia", "Montague", "Helen", "Ozzy", "Stef", "Debra", "Maxene", "Stefanie", "Russ", "Avril",
+            "Johnathan", "Orson", "Chelsey", "Josephine", "Deshaun", "Wendell", "Lula", "Ferdinanda", "Greg", "Brad",
+            "Kynaston", "Dena", "Russel", "Robertina", "Misti", "Leon", "Anjelica", "Bryana", "Myles", "Judi", "Curtis",
+            "Davin", "Kristia", "Chrysanta", "Hayleigh", "Hector", "Osbert", "Eustace", "Cary", "Tansy", "Cayley",
+            "Maryann", "Alissa", "Ike", "Tranter", "Reina", "Alwilda", "Sidony", "Columbine", "Astra", "Jillie",
+            "Stephania", "Jonah", "Kennedy", "Ferdinand", "Allegria", "Donella", "Kelleigh", "Darian", "Eldreda",
+            "Jayden", "Herbie", "Jake", "Winston", "Vi", "Annie", "Cherice", "Hugo", "Tricia", "Haydee", "Cassarah",
+            "Darden", "Mallory", "Alton", "Hadley", "Romayne", "Lacey", "Ern", "Alayna", "Cecilia", "Seward", "Tilly",
+            "Edgar", "Concordia", "Ibbie", "Dahlia", "Oswin", "Stu", "Brett", "Maralyn", "Kristeen", "Dotty", "Robyn",
+            "Nessa", "Tresha", "Guinevere", "Emerson", "Haze", "Lyn", "Henderson", "Lexa", "Jaylen", "Gail", "Lizette",
+            "Tiara", "Robbie", "Destiny", "Alice", "Livia", "Rosy", "Leah", "Jan", "Zach", "Vita", "Gia", "Micheal",
+            "Rowina", "Alysha", "Bobbi", "Delores", "Osmond", "Karaugh", "Wilbur", "Kasandra", "Renae", "Kaety", "Dora",
+            "Gaye", "Amaryllis", "Katelyn", "Dacre", "Prudence", "Ebony", "Camron", "Jerrold", "Vivyan", "Randall",
+            "Donna", "Misty", "Damon", "Selby", "Esmund", "Rian", "Garry", "Julius", "Raelene", "Clement", "Dom",
+            "Tibby", "Moss", "Millicent", "Gwendoline", "Berry", "Ashleigh", "Lilac", "Quin", "Vere", "Creighton",
+            "Harriet", "Malvina", "Lianne", "Pearle", "Kizzie", "Kara", "Petula", "Jeanie", "Maria", "Pacey",
+            "Victoria", "Huey", "Toni", "Rose", "Wallis", "Diggory", "Josiah", "Delma", "Keysha", "Channing", "Prue",
+            "Lee", "Ryan", "Sidney", "Valerie", "Clancy", "Ezra", "Gilbert", "Clare", "Laz", "Crofton", "Mike",
+            "Annabella", "Tara", "Eldred", "Arthur", "Jaylon", "Peronel", "Paden", "Dot", "Marian", "Amyas", "Alexus",
+            "Esmond", "Abbie", "Stanley", "Brittani", "Vickie", "Errol", "Kimberlee", "Uland", "Ebenezer", "Howie",
+            "Eveline", "Andrea", "Trish", "Hopkin", "Bryanna", "Temperance", "Valarie", "Femie", "Alix", "Terrell",
+            "Lewin", "Lorrin", "Happy", "Micah", "Rachyl", "Sloan", "Gertrude", "Elizabeth", "Dorris", "Andra", "Bram",
+            "Gary", "Jeannine", "Maurene", "Irene", "Yolonda", "Jonty", "Coleen", "Cecelia", "Chantal", "Stuart",
+            "Caris", "Ros", "Kaleigh", "Mirabelle", "Kolby", "Primrose", "Susannah", "Ginny", "Jinny", "Dolly",
+            "Lettice", "Sonny", "Melva", "Ernest", "Garret", "Reagan", "Trenton", "Gallagher", "Edwin", "Nikolas",
+            "Corrie", "Lynette", "Ettie", "Sly", "Debbi", "Eudora", "Brittney", "Tacey", "Marius", "Anima", "Gordon",
+            "Olivia", "Kortney", "Shantel", "Kolleen", "Nevaeh", "Buck", "Sera", "Liliana", "Aric", "Kalyn", "Mick",
+            "Libby", "Ingram", "Alexandria", "Darleen", "Jacklyn", "Hughie", "Tyler", "Aida", "Ronda", "Deemer",
+            "Taryn", "Laureen", "Samantha", "Dave", "Hardy", "Baldric", "Montgomery", "Gus", "Ellis", "Titania", "Luke",
+            "Chase", "Haidee", "Mayra", "Isabell", "Trinity", "Milo", "Abigail", "Tacita", "Meg", "Hervey", "Natasha",
+            "Sadie", "Holden", "Dee", "Mansel", "Perry", "Randi", "Frederica", "Georgina", "Kolour", "Debbie",
+            "Seraphina", "Elspet", "Julyan", "Raven", "Zavia", "Jarvis", "Jaymes", "Grover", "Cairo", "Alea", "Jordon",
+            "Braxton", "Donny", "Rhoda", "Tonya", "Bee", "Alyssia", "Ashlyn", "Reanna", "Lonny", "Arlene", "Deb",
+            "Jane", "Nikole", "Bettina", "Harrison", "Tamzen", "Arielle", "Adelaide", "Faith", "Bridie", "Wilburn",
+            "Fern", "Nan", "Shaw", "Zeke", "Alan", "Dene", "Gina", "Alexa", "Bailey", "Sal", "Tammy", "Maximillian",
+            "America", "Sylvana", "Fitz", "Mo", "Marissa", "Cass", "Eldon", "Wilfrid", "Tel", "Joann", "Kendra",
+            "Tolly", "Leanne", "Ferdie", "Haven", "Lucas", "Marlee", "Cyrilla", "Red", "Phoenix", "Jazmin", "Carin",
+            "Gena", "Lashonda", "Tucker", "Genette", "Kizzy", "Winifred", "Melody", "Keely", "Kaylyn", "Radcliff",
+            "Lettie", "Foster", "Lyndsey", "Nicholas", "Farley", "Louisa", "Dana", "Dortha", "Francine", "Doran",
+            "Bonita", "Hal", "Sawyer", "Reginald", "Aislin", "Nathan", "Baylee", "Abilene", "Ladonna", "Maurine",
+            "Shelly", "Deandre", "Jasmin", "Roderic", "Tiffany", "Amanda", "Verity", "Wilford", "Gayelord", "Whitney",
+            "Demelza", "Kenton", "Alberta", "Kyra", "Tabitha", "Sampson", "Korey", "Lillian", "Edison", "Clayton",
+            "Steph", "Maya", "Dusty", "Jim", "Ronny", "Adrianne", "Bernard", "Harris", "Kiley", "Alexander", "Kisha",
+            "Ethalyn", "Patience", "Briony", "Indigo", "Aureole", "Makenzie", "Molly", "Sherilyn", "Barry", "Laverne",
+            "Hunter", "Rocky", "Tyreek", "Madalyn", "Phyliss", "Chet", "Beatrice", "Faye", "Lavina", "Madelyn",
+            "Tracey", "Gyles", "Patti", "Carlyn", "Stephanie", "Jackalyn", "Larrie", "Kimmy", "Isolda", "Emelina",
+            "Lis", "Zillah", "Cody", "Sheard", "Rufus", "Paget", "Mae", "Rexanne", "Luvinia", "Tamsen", "Rosanna",
+            "Greig", "Stacia", "Mabelle", "Quianna", "Lotus", "Delice", "Bradford", "Angus", "Cosmo", "Earlene",
+            "Adrian", "Arlie", "Noelle", "Sabella", "Isa", "Adelle", "Innocent", "Kirby", "Trixie", "Kenelm", "Nelda",
+            "Melia", "Kendal", "Dorinda", "Placid", "Linette", "Kam", "Sherisse", "Evan", "Ewart", "Janice", "Linton",
+            "Jacaline", "Charissa", "Douglas", "Aileen", "Kemp", "Oli", "Amethyst", "Rosie", "Nigella", "Sherill",
+            "Anderson", "Alanna", "Eric", "Claudia", "Jennifer", "Boniface", "Harriet", "Vernon", "Lucy", "Shawnee",
+            "Gerard", "Cecily", "Romey", "Randall", "Wade", "Lux", "Dawson", "Gregg", "Kade", "Roxanne", "Melinda",
+            "Rolland", "Rowanne", "Fannie", "Isidore", "Melia", "Harvie", "Salal", "Eleonor", "Jacquette", "Lavone",
+            "Shanika", "Tarquin", "Janet", "Josslyn", "Maegan", "Augusta", "Aubree", "Francene", "Martie", "Marisa",
+            "Tyreek", "Tatianna", "Caleb", "Sheridan", "Nellie", "Barbara", "Wat", "Jayla", "Esmaralda", "Graeme",
+            "Lavena", "Jemima", "Nikolas", "Triston", "Portia", "Kyla", "Marcus", "Raeburn", "Jamison", "Earl", "Wren",
+            "Leighton", "Lagina", "Lucasta", "Dina", "Amaranta", "Jessika", "Claud", "Bernard", "Winifred", "Ebba",
+            "Sammi", "Gall", "Chloe", "Ottoline", "Herbert", "Janice", "Gareth", "Channing", "Caleigh", "Kailee",
+            "Ralphie", "Tamzen", "Quincy", "Beaumont", "Albert", "Jadyn", "Violet", "Luanna", "Moriah", "Humbert",
+            "Jed", "Leona", "Hale", "Mitch", "Marlin", "Nivek", "Darwin", "Dirk", "Liliana", "Meadow", "Bernadine",
+            "Jorie", "Peyton", "Astra", "Roscoe", "Gina", "Lovell", "Jewel", "Romayne", "Rosy", "Imogene", "Margaretta",
+            "Lorinda", "Hopkin", "Bobby", "Flossie", "Bennie", "Horatio", "Jonah", "Lyn", "Deana", "Juliana", "Blanch",
+            "Wright", "Kendal", "Woodrow", "Tania", "Austyn", "Val", "Mona", "Charla", "Rudyard", "Pamela", "Raven",
+            "Zena", "Nicola", "Kaelea", "Conor", "Virgil", "Sonnie", "Goodwin", "Christianne", "Linford", "Myron",
+            "Denton", "Charita", "Brody", "Ginnie", "Harrison", "Jeanine", "Quin", "Isolda", "Zoie", "Pearce", "Margie",
+            "Larrie", "Angelina", "Marcia", "Jessamine", "Delilah", "Dick", "Luana", "Delicia", "Lake", "Luvenia",
+            "Vaughan", "Concordia", "Gayelord", "Cheyenne", "Felix", "Dorris", "Pen", "Kristeen", "Parris", "Everitt",
+            "Josephina", "Amy", "Tommie", "Adrian", "April", "Rosaline", "Zachery", "Trace", "Phoebe", "Jenelle",
+            "Kameron", "Katharine", "Media", "Colton", "Tad", "Quianna", "Kerenza", "Greta", "Luvinia", "Pete", "Tonya",
+            "Beckah", "Barbra", "Jon", "Tetty", "Corey", "Sylvana", "Kizzy", "Korey", "Trey", "Haydee", "Penny",
+            "Mandy", "Panda", "Coline", "Ramsey", "Sukie", "Annabel", "Sarina", "Corbin", "Suzanna", "Rob", "Duana",
+            "Shell", "Jason", "Eddy", "Rube", "Roseann", "Celia", "Brianne", "Nerissa", "Jera", "Humphry", "Ashlynn",
+            "Terrence", "Philippina", "Coreen", "Kolour", "Indiana", "Paget", "Marlyn", "Hester", "Isbel", "Ocean",
+            "Harris", "Leslie", "Vere", "Monroe", "Isabelle", "Bertie", "Clitus", "Dave", "Alethea", "Lessie", "Louiza",
+            "Madlyn", "Garland", "Wolf", "Lalo", "Donny", "Amabel", "Tianna", "Louie", "Susie", "Mackenzie", "Renie",
+            "Tess", "Marmaduke", "Gwendolen", "Bettina", "Beatrix", "Esmund", "Minnie", "Carlie", "Barnabas", "Ruthie",
+            "Honour", "Haylie", "Xavior", "Freddie", "Ericka", "Aretha", "Edie", "Madelina", "Anson", "Tabby",
+            "Derrick", "Jocosa", "Deirdre", "Aislin", "Chastity", "Abigail", "Wynonna", "Zo", "Eldon", "Krystine",
+            "Ghislaine", "Zavia", "Nolene", "Marigold", "Kelley", "Sylvester", "Odell", "George", "Laurene", "Franklyn",
+            "Clarice", "Mo", "Dustin", "Debbi", "Lina", "Tony", "Acacia", "Hettie", "Natalee", "Marcie", "Brittany",
+            "Elnora", "Rachel", "Dawn", "Basil", "Christal", "Anjelica", "Fran", "Tawny", "Delroy", "Tameka", "Lillie",
+            "Ceara", "Deanna", "Deshaun", "Ken", "Bradford", "Justina", "Merle", "Draven", "Gretta", "Harriette",
+            "Webster", "Nathaniel", "Anemone", "Coleen", "Ruth", "Chryssa", "Hortensia", "Saffie", "Deonne", "Leopold",
+            "Harlan", "Lea", "Eppie", "Lucinda", "Tilda", "Fanny", "Titty", "Lockie", "Jepson", "Sherisse", "Maralyn",
+            "Ethel", "Sly", "Ebenezer", "Canute", "Ella", "Freeman", "Reuben", "Olivette", "Nona", "Rik", "Amice",
+            "Kristine", "Kathie", "Jayne", "Jeri", "Mckenna", "Bertram", "Kaylee", "Livia", "Gil", "Wallace", "Maryann",
+            "Keeleigh", "Laurinda", "Doran", "Khloe", "Dakota", "Yaron", "Kimberleigh", "Gytha", "Doris", "Marylyn",
+            "Benton", "Linnette", "Esther", "Jakki", "Rowina", "Marian", "Roselyn", "Norbert", "Maggie", "Caesar",
+            "Phinehas", "Jerry", "Jasmine", "Antonette", "Miriam", "Monna", "Maryvonne", "Jacquetta", "Bernetta",
+            "Napier", "Annie", "Gladwin", "Sheldon", "Aric", "Elouise", "Gawain", "Kristia", "Gabe", "Kyra", "Red",
+            "Tod", "Dudley", "Lorraine", "Ryley", "Sabina", "Poppy", "Leland", "Aileen", "Eglantine", "Alicia", "Jeni",
+            "Addy", "Tiffany", "Geffrey", "Lavina", "Collin", "Clover", "Vin", "Jerome", "Doug", "Vincent", "Florence",
+            "Scarlet", "Celeste", "Desdemona", "Tiphanie", "Kassandra", "Ashton", "Madison", "Art", "Magdalene", "Iona",
+            "Josepha", "Anise", "Ferne", "Derek", "Huffie", "Qiana", "Ysabel", "Tami", "Shannah", "Xavier", "Willard",
+            "Winthrop", "Vickie", "Maura", "Placid", "Tiara", "Reggie", "Elissa", "Isa", "Chrysanta", "Jeff", "Bessie",
+            "Terri", "Amilia", "Brett", "Daniella", "Damion", "Carolina", "Maximillian", "Travers", "Benjamin", "Oprah",
+            "Darcy", "Yolanda", "Nicolina", "Crofton", "Jarrett", "Kaitlin", "Shauna", "Keren", "Bevis", "Kalysta",
+            "Sharron", "Alyssa", "Blythe", "Zelma", "Caelie", "Norwood", "Billie", "Patrick", "Gary", "Cambria",
+            "Tylar", "Mason", "Helen", "Melyssa", "Gene", "Gilberta", "Carter", "Herbie", "Harmonie", "Leola",
+            "Eugenia", "Clint", "Pauletta", "Edwyna", "Georgina", "Teal", "Harper", "Izzy", "Dillon", "Kezia",
+            "Evangeline", "Colene", "Madelaine", "Zilla", "Rudy", "Dottie", "Caris", "Morton", "Marge", "Tacey",
+            "Parker", "Troy", "Liza", "Lewin", "Tracie", "Justine", "Dallas", "Linden", "Ray", "Loretta", "Teri",
+            "Elvis", "Diane", "Julianna", "Manfred", "Denise", "Eireen", "Ann", "Kenith", "Linwood", "Kathlyn",
+            "Bernice", "Shelley", "Oswald", "Amedeus", "Homer", "Tanzi", "Ted", "Ralphina", "Hyacinth", "Lotus",
+            "Matthias", "Arlette", "Clark", "Cecil", "Elspeth", "Alvena", "Noah", "Millard", "Brenden", "Cole",
+            "Philipa", "Nina", "Thelma", "Iantha", "Reid", "Jefferson", "Meg", "Elsie", "Shirlee", "Nathan", "Nancy",
+            "Simona", "Racheal", "Carin", "Emory", "Delice", "Kristi", "Karaugh", "Kaety", "Tilly", "Em", "Alanis",
+            "Darrin", "Jerrie", "Hollis", "Cary", "Marly", "Carita", "Jody", "Farley", "Hervey", "Rosalin", "Cuthbert",
+            "Stewart", "Jodene", "Caileigh", "Briscoe", "Dolores", "Sheree", "Eustace", "Nigel", "Detta", "Barret",
+            "Rowland", "Kenny", "Githa", "Zoey", "Adela", "Petronella", "Opal", "Coleman", "Niles", "Cyril", "Dona",
+            "Alberic", "Allannah", "Jules", "Avalon", "Hadley", "Thomas", "Renita", "Calanthe", "Heron", "Shawnda",
+            "Chet", "Malina", "Manny", "Rina", "Frieda", "Eveleen", "Deshawn", "Amos", "Raelene", "Paige", "Molly",
+            "Nannie", "Ileen", "Brendon", "Milford", "Unice", "Rebeccah", "Caedmon", "Gae", "Doreen", "Vivian", "Louis",
+            "Raphael", "Vergil", "Lise", "Glenn", "Karyn", "Terance", "Reina", "Jake", "Gordon", "Wisdom", "Isiah",
+            "Gervase", "Fern", "Marylou", "Roddy", "Justy", "Derick", "Shantelle", "Adam", "Chantel", "Madoline",
+            "Emmerson", "Lexie", "Mickey", "Stephen", "Dane", "Stacee", "Elwin", "Tracey", "Alexandra", "Ricky", "Ian",
+            "Kasey", "Rita", "Alanna", "Georgene", "Deon", "Zavier", "Ophelia", "Deforest", "Lowell", "Zubin", "Hardy",
+            "Osmund", "Tabatha", "Debby", "Katlyn", "Tallulah", "Priscilla", "Braden", "Wil", "Keziah", "Jen", "Aggie",
+            "Korbin", "Lemoine", "Barnaby", "Tranter", "Goldie", "Roderick", "Trina", "Emery", "Pris", "Sidony",
+            "Adelle", "Tate", "Wilf", "Zola", "Brande", "Chris", "Calanthia", "Lilly", "Kaycee", "Lashonda", "Jasmin",
+            "Elijah", "Shantel", "Simon", "Rosalind", "Jarod", "Kaylie", "Corrine", "Joselyn", "Archibald",
+            "Mariabella", "Winton", "Merlin", "Chad", "Ursula", "Kristopher", "Hewie", "Adrianna", "Lyndsay", "Jasmyn",
+            "Tim", "Evette", "Margaret", "Samson", "Bronte", "Terence", "Leila", "Candice", "Tori", "Jamey",
+            "Coriander", "Conrad", "Floyd", "Karen", "Lorin", "Maximilian", "Cairo", "Emily", "Yasmin", "Karolyn",
+            "Bryan", "Lanny", "Kimberly", "Rick", "Chaz", "Krystle", "Lyric", "Laura", "Garrick", "Flip", "Monty",
+            "Brendan", "Ermintrude", "Rayner", "Merla", "Titus", "Marva", "Patricia", "Leone", "Tracy", "Jaqueline",
+            "Hallam", "Delores", "Cressida", "Carlyle", "Leann", "Kelcey", "Laurence", "Ryan", "Reynold", "Mark",
+            "Collyn", "Audie", "Sammy", "Ellery", "Sallie", "Pamelia", "Adolph", "Lydia", "Titania", "Ron", "Bridger",
+            "Aline", "Read", "Kelleigh", "Weldon", "Irving", "Garey", "Diggory", "Evander", "Kylee", "Deidre", "Ormond",
+            "Laurine", "Reannon", "Arline", "Pat"
+
+    };
+
+    public static String[] jargon = { "wireless", "signal", "network", "3G", "plan", "touch-screen", "customer-service",
+            "reachability", "voice-command", "shortcut-menu", "customization", "platform", "speed", "voice-clarity",
+            "voicemail-service" };
+
+    public static String[] vendors = { "at&t", "verizon", "t-mobile", "sprint", "motorola", "samsung", "iphone" };
+
+    public static String[] org_list = { "Latsonity", "ganjalax", "Zuncan", "Lexitechno", "Hot-tech", "subtam",
+            "Coneflex", "Ganjatax", "physcane", "Tranzap", "Qvohouse", "Zununoing", "jaydax", "Keytech", "goldendexon",
+            "Villa-tech", "Trustbam", "Newcom", "Voltlane", "Ontohothex", "Ranhotfan", "Alphadax", "Transhigh",
+            "kin-ron", "Doublezone", "Solophase", "Vivaace", "silfind", "Basecone", "sonstreet", "Freshfix",
+            "Techitechi", "Kanelectrics", "linedexon", "Goldcity", "Newfase", "Technohow", "Zimcone", "Salthex",
+            "U-ron", "Solfix", "whitestreet", "Xx-technology", "Hexviafind", "over-it", "Strongtone", "Tripplelane",
+            "geomedia", "Scotcity", "Inchex", "Vaiatech", "Striptaxon", "Hatcom", "tresline", "Sanjodax", "freshdox",
+            "Sumlane", "Quadlane", "Newphase", "overtech", "Voltbam", "Icerunin", "Fixdintex", "Hexsanhex", "Statcode",
+            "Greencare", "U-electrics", "Zamcorporation", "Ontotanin", "Tanzimcare", "Groovetex", "Ganjastrip",
+            "Redelectronics", "Dandamace", "Whitemedia", "strongex", "Streettax", "highfax", "Mathtech", "Xx-drill",
+            "Sublamdox", "Unijobam", "Rungozoom", "Fixelectrics", "Villa-dox", "Ransaofan", "Plexlane", "itlab",
+            "Lexicone", "Fax-fax", "Viatechi", "Inchdox", "Kongreen", "Doncare", "Y-geohex", "Opeelectronics",
+            "Medflex", "Dancode", "Roundhex", "Labzatron", "Newhotplus", "Sancone", "Ronholdings", "Quoline",
+            "zoomplus", "Fix-touch", "Codetechno", "Tanzumbam", "Indiex", "Canline" };
+
+    public static void main(String[] args) throws Exception {
+        DataGeneratorForSpatialIndexEvaluation dg = new DataGeneratorForSpatialIndexEvaluation(
+                new InitializationInfo());
+        TweetMessageIterator tmi = dg.new TweetMessageIterator(1, new GULongIDGenerator(0, (byte) 0));
+        int len = 0;
+        int count = 0;
+        while (tmi.hasNext()) {
+            String tm = tmi.next().toString();
+            System.out.println(tm);
+            len += tm.length();
+            ++count;
+        }
+        System.out.println(DataGeneratorForSpatialIndexEvaluation.DUMMY_SIZE_ADJUSTER.length());
+        System.out.println(len);
+        System.out.println(count);
+        System.out.println(len / count);
+    }
+}
\ No newline at end of file
diff --git a/asterix-tools/src/main/java/org/apache/asterix/tools/external/data/GULongIDGenerator.java b/asterix-tools/src/main/java/org/apache/asterix/tools/external/data/GULongIDGenerator.java
new file mode 100644
index 0000000..00f3bcb
--- /dev/null
+++ b/asterix-tools/src/main/java/org/apache/asterix/tools/external/data/GULongIDGenerator.java
@@ -0,0 +1,50 @@
+/*
+ * 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.asterix.tools.external.data;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class GULongIDGenerator {
+
+    private final int partition;
+    private final long baseValue;
+    private final AtomicLong nextValue;
+
+    public GULongIDGenerator(int partition, byte seed) {
+        this.partition = partition;
+        ByteBuffer buffer = ByteBuffer.allocate(8);
+        buffer.put(seed);
+        buffer.put((byte) partition);
+        buffer.putInt(0);
+        buffer.putShort((short) 0);
+        buffer.flip();
+        this.baseValue = new Long(buffer.getLong());
+        this.nextValue = new AtomicLong(baseValue);
+    }
+
+    public long getNextULong() {
+        return nextValue.incrementAndGet();
+    }
+
+    public int getPartition() {
+        return partition;
+    }
+
+}
diff --git a/asterix-tools/src/main/java/org/apache/asterix/tools/external/data/TweetGeneratorForSpatialIndexEvaluation.java b/asterix-tools/src/main/java/org/apache/asterix/tools/external/data/TweetGeneratorForSpatialIndexEvaluation.java
new file mode 100644
index 0000000..fcaa2a4
--- /dev/null
+++ b/asterix-tools/src/main/java/org/apache/asterix/tools/external/data/TweetGeneratorForSpatialIndexEvaluation.java
@@ -0,0 +1,139 @@
+/*
+ * 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.asterix.tools.external.data;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.asterix.tools.external.data.DataGeneratorForSpatialIndexEvaluation.InitializationInfo;
+import org.apache.asterix.tools.external.data.DataGeneratorForSpatialIndexEvaluation.TweetMessage;
+import org.apache.asterix.tools.external.data.DataGeneratorForSpatialIndexEvaluation.TweetMessageIterator;
+
+public class TweetGeneratorForSpatialIndexEvaluation {
+
+    private static Logger LOGGER = Logger.getLogger(TweetGeneratorForSpatialIndexEvaluation.class.getName());
+
+    public static final String KEY_DURATION = "duration";
+    public static final String KEY_TPS = "tps";
+    public static final String KEY_GUID_SEED = "guid-seed";
+    public static final String KEY_OPENSTREETMAP_FILEPATH = "open-street-map-filepath";
+    public static final String KEY_LOCATION_SAMPLE_INTERVAL = "location-sample-interval";
+
+    public static final String OUTPUT_FORMAT = "output-format";
+    public static final String OUTPUT_FORMAT_ARECORD = "arecord";
+    public static final String OUTPUT_FORMAT_ADM_STRING = "adm-string";
+
+    private static final int DEFAULT_DURATION = 60; //seconds
+    private static final int DEFAULT_GUID_SEED = 0;
+    private static final int DEFAULT_SAMPLE_INTERVAL = 1;
+
+    private int duration;
+    private TweetMessageIterator tweetIterator = null;
+    private int partition;
+    private int tweetCount = 0;
+    private int frameTweetCount = 0;
+    private int numFlushedTweets = 0;
+    private OutputStream os;
+    private DataGeneratorForSpatialIndexEvaluation dataGenerator = null;
+    private ByteBuffer outputBuffer = ByteBuffer.allocate(32 * 1024);
+    private GULongIDGenerator uidGenerator;
+    private String openStreetMapFilePath;
+    private int locationSampleInterval;
+
+    public int getTweetCount() {
+        return tweetCount;
+    }
+
+    public TweetGeneratorForSpatialIndexEvaluation(Map<String, String> configuration, int partition, String format,
+            OutputStream os) throws Exception {
+        this.partition = partition;
+        String value = configuration.get(KEY_DURATION);
+        this.duration = value != null ? Integer.parseInt(value) : DEFAULT_DURATION;
+        openStreetMapFilePath = configuration.get(KEY_OPENSTREETMAP_FILEPATH);
+        String lsi = configuration.get(KEY_LOCATION_SAMPLE_INTERVAL);
+        this.locationSampleInterval = lsi != null ? Integer.parseInt(lsi) : DEFAULT_SAMPLE_INTERVAL;
+        int guidSeed = configuration.get(KEY_GUID_SEED) != null ? Integer.parseInt(configuration.get(KEY_GUID_SEED))
+                : DEFAULT_GUID_SEED;
+        uidGenerator = new GULongIDGenerator(partition, (byte) (guidSeed));
+        dataGenerator = new DataGeneratorForSpatialIndexEvaluation(new InitializationInfo(), openStreetMapFilePath,
+                locationSampleInterval);
+        tweetIterator = dataGenerator.new TweetMessageIterator(duration, uidGenerator);
+        this.os = os;
+    }
+
+    private void writeTweetString(TweetMessage tweetMessage) throws IOException {
+        String tweet = tweetMessage.toString() + "\n";
+        tweetCount++;
+        byte[] b = tweet.getBytes();
+        if (outputBuffer.position() + b.length > outputBuffer.limit()) {
+            flush();
+            numFlushedTweets += frameTweetCount;
+            frameTweetCount = 0;
+            outputBuffer.put(b);
+        } else {
+            outputBuffer.put(b);
+        }
+        frameTweetCount++;
+    }
+
+    public int getNumFlushedTweets() {
+        return numFlushedTweets;
+    }
+
+    private void flush() throws IOException {
+        outputBuffer.flip();
+        os.write(outputBuffer.array(), 0, outputBuffer.limit());
+        outputBuffer.position(0);
+        outputBuffer.limit(32 * 1024);
+    }
+
+    public boolean setNextRecordBatch(int numTweetsInBatch) throws Exception {
+        boolean moreData = tweetIterator.hasNext();
+        if (!moreData) {
+            if (outputBuffer.position() > 0) {
+                flush();
+                numFlushedTweets += frameTweetCount;
+                frameTweetCount = 0;
+            }
+            if (LOGGER.isLoggable(Level.INFO)) {
+                LOGGER.info("Reached end of batch. Tweet Count: [" + partition + "]" + tweetCount);
+            }
+            return false;
+        } else {
+            int count = 0;
+            while (count < numTweetsInBatch) {
+                writeTweetString(tweetIterator.next());
+                count++;
+            }
+            return true;
+        }
+    }
+
+    public void resetDurationAndFlushedTweetCount(int duration) {
+        tweetIterator.resetDuration(duration);
+        numFlushedTweets = 0;
+        tweetCount = 0;
+
+    }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index e69ae24..581b8b7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -370,6 +370,7 @@
         <module>asterix-fuzzyjoin</module>
         <module>asterix-yarn</module>
         <module>asterix-replication</module>
+        <module>asterix-experiments</module>
     </modules>
 
     <repositories>