Revision: 177
http://polepos.svn.sourceforge.net/polepos/?rev=177&view=rev
Author: carlrosenberger
Date: 2011-02-02 13:59:56 +0000 (Wed, 02 Feb 2011)
Log Message:
-----------
cr + acv: Work on an external narrative file to explain the circuits.
Added Paths:
-----------
trunk/polepos/doc/circuits.html
Added: trunk/polepos/doc/circuits.html
===================================================================
--- trunk/polepos/doc/circuits.html (rev 0)
+++ trunk/polepos/doc/circuits.html 2011-02-02 13:59:56 UTC (rev 177)
@@ -0,0 +1,309 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+ <head>
+ <title>PolePosition Circuits</title>
+ <link rel="stylesheet" href="style.css" type="text/css">
+ </head>
+ <body>
+ <h1>PolePosition Circuits</h1>
+ <p>This file explains what each circuit of the Poleposition benchmark does.
+ </p>
+ <hr>
+ <h2>Content</h2>
+ <p>
+ <ul>
+ <li>
+ <a href="#complex">Complex</a>
+ <li>
+ <a href="#nestedlists">Nestedlists</a>
+ <li>
+ <a href="#inheritancehierarchy">Inheritancehierarchy</a>
+ <li>
+ <a href="#flatobject">Flatobject</a>
+ </li>
+ </ul>
+ <P></P>
+ <hr>
+ <a name="complex"></a>
+ <h2>Complex</h2>
+ <p>
+ The Complex circuit simulates writing, reading, querying and updating a deep
+ object graph that is composed of multiple different classes with an inheritance hierarchy of 5
+ levels. The sources for the implementations can be found here:</p>
+ <ul>
+ <li><a href="https://polepos.svn.sourceforge.net/svnroot/polepos/trunk/polepos/src/org/polepos/teams/db4o/ComplexDb4o.java">ComplexDb4o.java</a></li>
+ <li><a href="https://polepos.svn.sourceforge.net/svnroot/polepos/trunk/polepos/src/org/polepos/teams/jdo/ComplexJdo.java">ComplexJdo.java</a></li>
+ <li><a href="https://polepos.svn.sourceforge.net/svnroot/polepos/trunk/polepos/src/org/polepos/teams/hibernate/ComplexHibernate.java">ComplexHibernate.java</a></li>
+ <li><a href="https://polepos.svn.sourceforge.net/svnroot/polepos/trunk/polepos/src/org/polepos/teams/db4o/ComplexJdbc.java">ComplexJdbc.java</a></li>
+ </ul>
+ <p>
+ In a nutshell the class model looks like this:</p>
+ <pre>
+class ComplexHolder0 {
+ String _name;
+ List <ComplexHolder0> _children;
+ ComplexHolder0[] _array;
+}
+
+class ComplexHolder1 extends ComplexHolder0 {
+ int _i1;
+}
+
+class ComplexHolder2 extends ComplexHolder1 {
+ int _i2;
+}
+
+class ComplexHolder3 extends ComplexHolder2 {
+ int _i3;
+}
+
+class ComplexHolder4 extends ComplexHolder3 {
+ int _i4;
+}
+</pre>
+<h3>Complex.write</h3>
+<p>ComplexHolder0#generate() generates a structure with depth and objectcount as
+ specificied in the configuration file. The _children List and the _array member
+ are again filled with ComplexHolder0 objects. Varying instances from
+ ComplexHolder0 to ComplexHolder4 are used.
+<p>Complex.write stores the complete graph
+ and measures the time taken for each database access technology.
+<h3>Complex.read</h3>
+<p>Complex.read accesses the root object of the structure that was generated with
+Complex.write, loads all attached objects into
+memory and traverses them, making sure that all objects are present by calculating
+a checksum over all objects.
+</p>
+<h3>Complex.query</h3>
+<p>
+Complex.query queries for ComplexHolder2 instances over the indexed _i2 field. The
+ query is run multiple times, specified by the selects property in the
+ configuration file. Sample queries look like this:</p>
+<pre>
+// db4o
+Query query = db().query();
+query.constrain(ComplexHolder2.class);
+query.descend("_i2").constrain(currentInt);
+ObjectSet<ComplexHolder2> result = query.execute();
+
+// JDO
+String filter = "this.i2 == param";
+Query query = db().newQuery(ComplexHolder2.class, filter);
+query.declareParameters("int param");
+Collection result = (Collection) query.execute(currentInt);
+
+// JDBC
+StringBuilder sb = new StringBuilder();
+sb.append("select " + HOLDER_TABLE0 + ".id from " + HOLDER_TABLE0);
+sb.append(" INNER JOIN " + HOLDER_TABLES[0]);
+sb.append(" on " + HOLDER_TABLE0 + ".id = " + HOLDER_TABLES[0] + ".id ");
+sb.append(" INNER JOIN " + HOLDER_TABLES[1]);
+sb.append(" on " + HOLDER_TABLE0 + ".id = " + HOLDER_TABLES[1] + ".id ");
+sb.append(" LEFT OUTER JOIN " + HOLDER_TABLES[2]);
+sb.append(" on " + HOLDER_TABLE0 + ".id = " + HOLDER_TABLES[2] + ".id ");
+sb.append(" LEFT OUTER JOIN " + HOLDER_TABLES[3]);
+sb.append(" on " + HOLDER_TABLE0 + ".id = " + HOLDER_TABLES[3] + ".id ");
+sb.append(" where " + HOLDER_TABLES[1] + ".i2 = ?");
+PreparedStatement stat = prepareStatement(sb.toString());
+ResultSet resultSet stat.executeQuery();
+</pre>
+<p>For JDBC we are only showing the main query. Reading individual object
+intances required another 150 lines of code with our implementation, see
+<a href="https://polepos.svn.sourceforge.net/svnroot/polepos/trunk/polepos/src/org/polepos/teams/db4o/ComplexJdbc.java">ComplexJdbc.java</a>.
+ </p>
+<h3>Complex.update</h3>
+<p>Complex.update reads the root object of the graph and traverses all
+holder objects, updates the name, copies all instances from the _children list
+to _array and stores the holder objects again.</p>
+<pre>
+// for each holder, do the following
+
+// OO
+holder.setName("updated");
+List <ComplexHolder0> children = holder.getChildren();
+ComplexHolder0[] array = new ComplexHolder0[children.size()];
+for (int i = 0; i < array.length; i++) {
+ array[i] = children.get(i);
+}
+holder.setArray(array);
+store(holder);
+
+// JDBC
+PreparedStatement nameStat = prepareStatement("update " + HOLDER_TABLE0 + " set name=? where id=?");
+PreparedStatement arrayDeleteStat = prepareStatement("delete from " + ARRAY_TABLE + " where parent = ?");
+PreparedStatement arrayInsertStat = prepareStatement("insert into tarray (parent, child, pos) values (?,?,?)");
+nameStat.setString(1, "updated");
+nameStat.setInt(2, holder.getId());
+nameStat.addBatch();
+arrayDeleteStat.setInt(1, holder.getId());
+arrayDeleteStat.addBatch();
+List <ComplexHolder0> children = holder.getChildren();
+for (int i = 0; i < children.size(); i++) {
+ arrayInsertStat.setInt(1, holder.getId());
+ arrayInsertStat.setInt(2, children.get(i).getId());
+ arrayInsertStat.setInt(3, i);
+ arrayInsertStat.addBatch();
+}
+</pre>
+<h3>Complex.delete</h3>
+<p>Complex.delete traverses all objects from the root and deletes each object individually.</p>
+ <hr>
+ <a name="nestedlists"></a>
+ <h2>Nestedlists</h2>
+ The Nestelists circuit simulates writing, reading, querying and updating a deep
+ graph of lists. Objects are partially reused within the lists.
+ The sources for the implementations can be found here:</p>
+ <ul>
+ <li><a href="https://polepos.svn.sourceforge.net/svnroot/polepos/trunk/polepos/src/org/polepos/teams/db4o/NestedListsDb4o.java">NestedListsDb4o.java</a></li>
+ <li><a href="https://polepos.svn.sourceforge.net/svnroot/polepos/trunk/polepos/src/org/polepos/teams/jdo/NestedListsJdo.java">NestedListsJdo.java</a></li>
+ <li><a href="https://polepos.svn.sourceforge.net/svnroot/polepos/trunk/polepos/src/org/polepos/teams/hibernate/NestedListsHibernate.java">NestedListsHibernate.java</a></li>
+ <li><a href="https://polepos.svn.sourceforge.net/svnroot/polepos/trunk/polepos/src/org/polepos/teams/db4o/NestedListsJdbc.java">NestedListsJdbc.java</a></li>
+ </ul>
+ <hr>
+<p>The class model for the NestedLists circuit looks like this:</p>
+<pre>
+class ListHolder {
+ private long _id;
+ private String _name;
+ List <ListHolder> _list;
+</pre>
+<h3>Nestedlists.create</h3>
+<p>ListHolder#generate() generates a deep structure of lists, reusing an amount of previous objects
+specified by the reuse property in the configuration file. Nestedlists.create stores the root of
+this generated graph and measures the time taken.</p>
+<pre>
+// OO
+db.store(ListHolder.generate(depth(), objectCount(), reuse()));
+db.commit();
+
+// JDBC
+ListHolder root = ListHolder.generate(depth(), objectCount(), reuse());
+final PreparedStatement listHolderStatement = prepareStatement("insert into " + LISTHOLDER_TABLE + " (fid, fname) values (?,?)");
+final PreparedStatement listStatement = prepareStatement("insert into " + LIST_TABLE + " (fid, fitem, felement) values (?,?,?)");
+_rootId = (int) root.id();
+root.accept(new Visitor<ListHolder>() {
+ @Override
+ public void visit(ListHolder listHolder) {
+ try {
+ int listHolderId = (int) listHolder.id();
+ listHolderStatement.setInt(ID, listHolderId);
+ listHolderStatement.setString(NAME, listHolder.name());
+ listHolderStatement.addBatch();
+ List<ListHolder> list = listHolder.list();
+ if(list != null && ! list.isEmpty()){
+ int position = 0;
+ for (ListHolder child : list) {
+ listStatement.setInt(ID, listHolderId);
+ listStatement.setInt(ITEM, (int) child.id());
+ listStatement.setInt(ELEMENT, position++);
+ listStatement.addBatch();
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+});
+listStatement.executeBatch();
+listHolderStatement.executeBatch();
+listStatement.close();
+listHolderStatement.close();
+commit();
+</pre>
+<h3>Nestedlists.read</h3>
+<p>Nestedlists.read loads the root object of the structure stored with Nestedlists.create
+and traverses all objects and adds them to the checksum.</p>
+<pre>
+// OO just traverses the root with a simple visitor
+
+@Override
+public void read() throws Throwable {
+ ListHolder root = root();
+ activate(root, Integer.MAX_VALUE);
+ root.accept(new Visitor<ListHolder>(){
+ public void visit(ListHolder listHolder){
+ addToCheckSum(listHolder);
+ }
+ });
+}
+
+private ListHolder root() {
+ Query query = db().query();
+ query.constrain(ListHolder.class);
+ query.descend("_name").constrain(ListHolder.ROOT_NAME);
+ ObjectSet objectSet = query.execute();
+ return (ListHolder) objectSet.next();
+}
+
+
+// JDBC requires a recursive read method and a set to check if an instance
+// was already loaded
+
+@Override
+public void read() throws Throwable {
+ ListHolder root = root();
+ root.accept(new Visitor<ListHolder>(){
+ public void visit(ListHolder listHolder){
+ addToCheckSum(listHolder);
+ }
+ });
+}
+
+private ListHolder root() throws SQLException {
+ PreparedStatement listHolderStatement = prepareStatement("select * from " + LISTHOLDER_TABLE + " where fid = ?");
+ PreparedStatement listStatement = prepareStatement("select * from " + LIST_TABLE + " where fid = ? order by felement");
+ Set<ListHolder> found = new HashSet<ListHolder>();
+ ListHolder root = recurseRead(listHolderStatement, listStatement, _rootId, found);
+ closePreparedStatement(listHolderStatement);
+ closePreparedStatement(listStatement);
+ return root;
+}
+
+private ListHolder recurseRead(PreparedStatement listHolderStatement,
+ PreparedStatement listStatement, int id, Set<ListHolder> found) throws SQLException {
+ listHolderStatement.setInt(ID, id);
+ ResultSet listHolderResultSet = listHolderStatement.executeQuery();
+ listHolderResultSet.next();
+ ListHolder listHolder = new ListHolder();
+ listHolder.id(id);
+ if(found.contains(listHolder)){
+ return listHolder;
+ }
+ found.add(listHolder);
+ listHolder.name(listHolderResultSet.getString(NAME));
+ listHolderResultSet.close();
+ listStatement.setInt(ID, id);
+
+ ResultSet listResultSet = listStatement.executeQuery();
+ List<Integer> ids = new ArrayList<Integer>();
+ if(listResultSet.next()){
+ do{
+ ids.add(listResultSet.getInt(ITEM));
+ } while(listResultSet.next());
+ listResultSet.close();
+ List <ListHolder> list = new ArrayList<ListHolder>();
+ for (Integer childId : ids) {
+ list.add(recurseRead(listHolderStatement, listStatement, childId, found));
+ }
+ listHolder.list(list);
+ }
+ return listHolder;
+}
+</pre>
+
+
+
+ <a name="inheritancehierarchy"></a>
+ <h2>Inheritancehierarchy</h2>
+ <p>As already expressed above, there is no best product. </p>
+ <hr>
+ <a name="flatobject"></a>
+ <h2>Flatobject</h2>
+ <p>
+ All sources of the PolePosition test suite including a couple of open source
+ database engines to run tests are available for download
+ <a href="http://sourceforge.net/project/showfiles.php?group_id=134549" target="_blank">here</a>.
+ </p>
+
+ </body>
+</html>
Property changes on: trunk/polepos/doc/circuits.html
___________________________________________________________________
Added: svn:mime-type
+ text/plain
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|