[Mulgara-svn] r1959 - in trunk/src/jar: content-mp3/java/org/mulgara/content/mp3 content-n3/java/org/mulgara/content/n3 content-rdfxml/java/org/mulgara/content/rdfxml krule/java/org/mulgara/krule query/java/org/mulgara/query resolver/java/org/mulgara/resolver resolver-gis/java/org/mulgara/resolver/gis resolver-memory/java/org/mulgara/resolver/memory resolver-nodetype/java/org/mulgara/resolver/nodetype resolver-null/java/org/mulgara/resolver/nullres resolver-prefix/java/org/mulgara/resolver/prefix resolver-relational/java/org/mulgara/resolver/relational resolver-spi/java/org/mulgara/resolver/spi resolver-url/java/org/mulgara/resolver/url server-rmi/java/org/mulgara/server/rmi store-stringpool-memory/java/org/mulgara/store/stringpool/memory store-stringpool-xa/java/org/mulgara/store/stringpool/xa store-stringpool-xa11/java/org/mulgara/store/stringpool/xa11 tuples/java/org/mulgara/store/tuples tuples-hybrid/java/org/mulgara/store/xa

alexhall at mulgara.org alexhall at mulgara.org
Wed Jun 30 15:58:54 UTC 2010


Author: alexhall
Date: 2010-06-30 15:58:53 +0000 (Wed, 30 Jun 2010)
New Revision: 1959

Modified:
   trunk/src/jar/content-mp3/java/org/mulgara/content/mp3/MP3Statements.java
   trunk/src/jar/content-n3/java/org/mulgara/content/n3/N3Statements.java
   trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/RDFXMLStatements.java
   trunk/src/jar/krule/java/org/mulgara/krule/Rule.java
   trunk/src/jar/query/java/org/mulgara/query/AnswerImpl.java
   trunk/src/jar/query/java/org/mulgara/query/ArrayAnswer.java
   trunk/src/jar/query/java/org/mulgara/query/BooleanAnswer.java
   trunk/src/jar/query/java/org/mulgara/query/Cursor.java
   trunk/src/jar/query/java/org/mulgara/query/GraphAnswer.java
   trunk/src/jar/query/java/org/mulgara/query/UnconstrainedAnswer.java
   trunk/src/jar/resolver-gis/java/org/mulgara/resolver/gis/GISDistanceStatements.java
   trunk/src/jar/resolver-gis/java/org/mulgara/resolver/gis/WritableGISResolver.java
   trunk/src/jar/resolver-memory/java/org/mulgara/resolver/memory/MemoryResolution.java
   trunk/src/jar/resolver-nodetype/java/org/mulgara/resolver/nodetype/TuplesWrapperResolution.java
   trunk/src/jar/resolver-null/java/org/mulgara/resolver/nullres/NullResolution.java
   trunk/src/jar/resolver-prefix/java/org/mulgara/resolver/prefix/TuplesWrapperResolution.java
   trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalAnswer.java
   trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolution.java
   trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/LocalizedTuples.java
   trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SingletonStatements.java
   trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/StatementsWrapperResolution.java
   trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/StatementsWrapperTuples.java
   trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/TripleSetWrapperStatements.java
   trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/TuplesWrapperResolution.java
   trunk/src/jar/resolver-url/java/org/mulgara/resolver/url/URLStatements.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/AppendAggregateTuples.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/CacheStatements.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/GlobalizedAnswer.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/SubqueryAnswer.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/TransactionalAnswer.java
   trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/AnswerWrapperRemoteAnswer.java
   trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/AnswerWrapperRemoteAnswerSerialised.java
   trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/BlankNodeWrapperAnswer.java
   trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteAnswer.java
   trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteAnswerWrapperAnswer.java
   trunk/src/jar/store-stringpool-memory/java/org/mulgara/store/stringpool/memory/MemoryStringPoolImpl.java
   trunk/src/jar/store-stringpool-xa/java/org/mulgara/store/stringpool/xa/XAStringPoolImpl.java
   trunk/src/jar/store-stringpool-xa11/java/org/mulgara/store/stringpool/xa11/XA11StringPoolImpl.java
   trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/HybridTuples.java
   trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/HybridTuplesFactory.java
   trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/HybridTuplesTest.java
   trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/MemoryCacheLine.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/Assignment.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/Difference.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/DistinctTuples.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/EmptyTuples.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/ExpandedProjection.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/FilteredTuples.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftFiltered.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoin.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/LetTuples.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/LiteralTuples.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedAppend.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedProjection.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuples.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnboundJoin.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnconstrainedTuples.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedAppend.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedProjection.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/WrappedTuples.java
Log:
Add a new isEmpty method as a more efficient way of testing for zero row cardinality when optimizing tuples operations

Modified: trunk/src/jar/content-mp3/java/org/mulgara/content/mp3/MP3Statements.java
===================================================================
--- trunk/src/jar/content-mp3/java/org/mulgara/content/mp3/MP3Statements.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/content-mp3/java/org/mulgara/content/mp3/MP3Statements.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -386,6 +386,10 @@
     return getRowCount();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return rowCount == 0;
+  }
+
   public boolean hasNoDuplicates() throws TuplesException {
     return false;
   }

Modified: trunk/src/jar/content-n3/java/org/mulgara/content/n3/N3Statements.java
===================================================================
--- trunk/src/jar/content-n3/java/org/mulgara/content/n3/N3Statements.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/content-n3/java/org/mulgara/content/n3/N3Statements.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -257,6 +257,7 @@
         // Create a new parser.
         try {
           p = new Parser(content, resolverSession);
+          p.start();
         } catch (NotModifiedException e) {
           throw new NotModifiedTuplesException(e);
         }

Modified: trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/RDFXMLStatements.java
===================================================================
--- trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/RDFXMLStatements.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/RDFXMLStatements.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -263,6 +263,7 @@
         // Create a new parser.
         try {
           p = new Parser(content, resolverSession);
+          parser.start();
         }
         catch (NotModifiedException e) {
           throw new NotModifiedTuplesException(e);

Modified: trunk/src/jar/krule/java/org/mulgara/krule/Rule.java
===================================================================
--- trunk/src/jar/krule/java/org/mulgara/krule/Rule.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/krule/java/org/mulgara/krule/Rule.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -337,6 +337,10 @@
       return cardinality;
     }
 
+    public boolean isEmpty() throws TuplesException {
+      return tuples.isEmpty();
+    }
+
     public long getRowCount() throws TuplesException {
       if (statementsPerRow > 1) {
         BigInteger rowCount = BigInteger.valueOf(tuples.getRowCount());

Modified: trunk/src/jar/query/java/org/mulgara/query/AnswerImpl.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/AnswerImpl.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/query/java/org/mulgara/query/AnswerImpl.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -238,6 +238,13 @@
     }
   }
 
+  /* (non-Javadoc)
+   * @see org.mulgara.query.Cursor#isEmpty()
+   */
+  public boolean isEmpty() throws TuplesException {
+    return getRowCardinality() == Cursor.ZERO;
+  }
+
   /**
    * How many solution terms does this answer comprise?
    *

Modified: trunk/src/jar/query/java/org/mulgara/query/ArrayAnswer.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ArrayAnswer.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/query/java/org/mulgara/query/ArrayAnswer.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -245,6 +245,13 @@
     }
   }
 
+  /* (non-Javadoc)
+   * @see org.mulgara.query.Cursor#isEmpty()
+   */
+  public boolean isEmpty() throws TuplesException {
+    return getRowCount() == 0;
+  }
+
   public Object getObject(int column) throws TuplesException {
     if (column < 0 || column >= variables.length) {
       throw new IllegalArgumentException("No such column " + column);

Modified: trunk/src/jar/query/java/org/mulgara/query/BooleanAnswer.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/BooleanAnswer.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/query/java/org/mulgara/query/BooleanAnswer.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -119,6 +119,13 @@
   }
 
   /**
+   * @see org.mulgara.query.Cursor#isEmpty()
+   */
+  public boolean isEmpty() throws TuplesException {
+    return false;
+  }
+
+  /**
    * @see org.mulgara.query.Cursor#getRowUpperBound()
    */
   public long getRowUpperBound() throws TuplesException {

Modified: trunk/src/jar/query/java/org/mulgara/query/Cursor.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/Cursor.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/query/java/org/mulgara/query/Cursor.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -145,6 +145,18 @@
   public int getRowCardinality() throws TuplesException;
 
   /**
+   * This method tests whether the cursor is known to be empty (i.e. have zero rows).
+   * It is intended for optimization purposes, when an empty test can be performed
+   * without actually evaluating the cursor.  It is possible for this method to
+   * return <tt>false</tt> and still have zero rows, but if this method returns
+   * <tt>true</tt> then it is guaranteed that the cursor has zero rows.
+   * 
+   * @return <tt>true</tt> if this cursor is known to contain no rows.
+   * @throws TuplesException Due to an error accessing the underlying data.
+   */
+  public boolean isEmpty() throws TuplesException;
+  
+  /**
    * Move to the next row.
    *
    * If no such row exists, return <code>false<code> and the current row

Modified: trunk/src/jar/query/java/org/mulgara/query/GraphAnswer.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/GraphAnswer.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/query/java/org/mulgara/query/GraphAnswer.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -141,6 +141,13 @@
   }
 
   /**
+   * @see org.mulgara.query.Cursor#isEmpty()
+   */
+  public boolean isEmpty() throws TuplesException {
+    return rawAnswer.isEmpty();
+  }
+
+  /**
    * @see org.mulgara.query.Cursor#getRowCount()
    */
   public long getRowCount() throws TuplesException {

Modified: trunk/src/jar/query/java/org/mulgara/query/UnconstrainedAnswer.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/UnconstrainedAnswer.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/query/java/org/mulgara/query/UnconstrainedAnswer.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -201,6 +201,10 @@
     return Cursor.ONE;
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return false;
+  }
+
   /**
    * @return a zero-length array
    */

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/AppendAggregateTuples.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/AppendAggregateTuples.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/AppendAggregateTuples.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -329,6 +329,10 @@
     return tuples.getRowCardinality();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return tuples.isEmpty();
+  }
+
   /**
    * @return the same value as the source column, or <code>true</code> in the
    *   case of appended aggregate columns (we have no certain way of knowing

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/CacheStatements.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/CacheStatements.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/CacheStatements.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -124,6 +124,11 @@
     return statements.getRowCardinality();
   }
 
+  public boolean isEmpty() throws TuplesException
+  {
+    return statements.isEmpty();
+  }
+  
   public Variable[] getVariables()
   {
     return statements.getVariables();

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/GlobalizedAnswer.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/GlobalizedAnswer.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/GlobalizedAnswer.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -161,6 +161,10 @@
     return tuples.getRowCardinality();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return tuples.isEmpty();
+  }
+
   public Variable[] getVariables() {
     return tuples.getVariables();
   }

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -311,7 +311,7 @@
 
   private Tuples projectSelectClause(Query query, Tuples result) throws TuplesException
   {
-    if (result.getRowCardinality() > Cursor.ZERO) {
+    if (!result.isEmpty()) {
       Tuples tmp = result;
       try {
         List variables = new ArrayList();
@@ -341,7 +341,7 @@
 
   private Tuples appendAggregates(Query query, Tuples result) throws TuplesException
   {
-    if (result.getRowCardinality() != Tuples.ZERO) {
+    if (!result.isEmpty()) {
       Tuples tmp = result;
       result = new AppendAggregateTuples(resolverSession, this, result,
           filterSubqueries(query.getVariableList()));

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/SubqueryAnswer.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/SubqueryAnswer.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/SubqueryAnswer.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -123,7 +123,7 @@
    * @throws TuplesException if it fails to get the row cardinality of the given tuples.
    */
   private void assignVariables(Tuples tuples, List<? extends SelectElement> variableList) throws TuplesException, IllegalArgumentException {
-    boolean empty = (tuples.getRowCardinality() == ZERO);
+    boolean empty = (tuples.isEmpty());
     this.variableList = variableList;
     this.variables = new Variable[variableList.size()];
     for (int i = 0; i < variableList.size(); i++) {

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/TransactionalAnswer.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/TransactionalAnswer.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/TransactionalAnswer.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -216,6 +216,15 @@
       }).getInt();
   }
 
+
+  public boolean isEmpty() throws TuplesException {
+    notClosed();
+    return transaction.execute(new AnswerOperation() {
+        public void execute() throws TuplesException {
+          returnBoolean(answer.isEmpty());
+        }
+      }).getBoolean();
+  }
   public boolean next() throws TuplesException {
     notClosed();
     return transaction.execute(new AnswerOperation() {

Modified: trunk/src/jar/resolver-gis/java/org/mulgara/resolver/gis/GISDistanceStatements.java
===================================================================
--- trunk/src/jar/resolver-gis/java/org/mulgara/resolver/gis/GISDistanceStatements.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-gis/java/org/mulgara/resolver/gis/GISDistanceStatements.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -167,7 +167,7 @@
     //find the Variables
     try {
       //check for emtpy Tuples
-      if (!(points.getRowCardinality() == Cursor.ZERO)) {
+      if (!(points.isEmpty())) {
         xIndex = points.getColumnIndex(X_VAR);
         xlatIndex = points.getColumnIndex(XLAT_VAR);
         xlongIndex = points.getColumnIndex(XLONG_VAR);
@@ -364,9 +364,16 @@
    * @throws TuplesException
    */
   public int getRowCardinality() throws TuplesException {
-    return points.getRowCardinality() * STATEMENTS_PER_ROW;
+    return points.getRowCardinality();
   }
 
+  /* (non-Javadoc)
+   * @see org.mulgara.query.Cursor#isEmpty()
+   */
+  public boolean isEmpty() throws TuplesException {
+    return points.isEmpty();
+  }
+
   /**
    * Determines which 'sub row' to return from the tuples.
    *
@@ -376,7 +383,7 @@
   public boolean next() throws TuplesException {
 
     //are there any statements?
-    if (points.getRowCardinality() == Cursor.ZERO) {
+    if (points.isEmpty()) {
       return false;
     }
 

Modified: trunk/src/jar/resolver-gis/java/org/mulgara/resolver/gis/WritableGISResolver.java
===================================================================
--- trunk/src/jar/resolver-gis/java/org/mulgara/resolver/gis/WritableGISResolver.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-gis/java/org/mulgara/resolver/gis/WritableGISResolver.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -285,7 +285,7 @@
    * @throws TuplesException
    */
   private boolean isEmpty(Cursor cursor) throws TuplesException {
-    return (cursor == null) || (cursor.getRowCardinality() == Cursor.ZERO);
+    return (cursor == null) || cursor.isEmpty() || (cursor.getRowCardinality() == Cursor.ZERO);
   }
 
   /**

Modified: trunk/src/jar/resolver-memory/java/org/mulgara/resolver/memory/MemoryResolution.java
===================================================================
--- trunk/src/jar/resolver-memory/java/org/mulgara/resolver/memory/MemoryResolution.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-memory/java/org/mulgara/resolver/memory/MemoryResolution.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -213,6 +213,10 @@
     return getRowCount();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return statingSet.isEmpty();
+  }
+
   public boolean hasNoDuplicates() throws TuplesException {
     return false;
   }

Modified: trunk/src/jar/resolver-nodetype/java/org/mulgara/resolver/nodetype/TuplesWrapperResolution.java
===================================================================
--- trunk/src/jar/resolver-nodetype/java/org/mulgara/resolver/nodetype/TuplesWrapperResolution.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-nodetype/java/org/mulgara/resolver/nodetype/TuplesWrapperResolution.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -180,6 +180,13 @@
     return tuples.getRowCardinality();
   }
 
+  /* (non-Javadoc)
+   * @see org.mulgara.query.Cursor#isEmpty()
+   */
+  public boolean isEmpty() throws TuplesException {
+    return tuples.isEmpty();
+  }
+
   /**
    * Accessor for the binding of a given variable within the current product
    * term (row).

Modified: trunk/src/jar/resolver-null/java/org/mulgara/resolver/nullres/NullResolution.java
===================================================================
--- trunk/src/jar/resolver-null/java/org/mulgara/resolver/nullres/NullResolution.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-null/java/org/mulgara/resolver/nullres/NullResolution.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -194,6 +194,11 @@
     return 0;
   }
 
+  /** @see org.mulgara.query.Cursor#isEmpty() */
+  public boolean isEmpty() throws TuplesException {
+    return true;
+  }
+
   /** @see org.mulgara.query.Cursor#getRowUpperBound() */
   public long getRowUpperBound() throws TuplesException {
     return 0;

Modified: trunk/src/jar/resolver-prefix/java/org/mulgara/resolver/prefix/TuplesWrapperResolution.java
===================================================================
--- trunk/src/jar/resolver-prefix/java/org/mulgara/resolver/prefix/TuplesWrapperResolution.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-prefix/java/org/mulgara/resolver/prefix/TuplesWrapperResolution.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -164,6 +164,13 @@
     return tuples.getRowCardinality();
   }
 
+  /* (non-Javadoc)
+   * @see org.mulgara.query.Cursor#isEmpty()
+   */
+  public boolean isEmpty() throws TuplesException {
+    return tuples.isEmpty();
+  }
+
   /**
    * Accessor for the binding of a given variable within the current product
    * term (row).

Modified: trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalAnswer.java
===================================================================
--- trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalAnswer.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalAnswer.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -176,6 +176,10 @@
   public int getRowCardinality() {
     return Cursor.MANY;
   }
+  
+  public boolean isEmpty() {
+    return false;
+  }
 
   public boolean next() throws TuplesException {
     if (queryList == null) {

Modified: trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolution.java
===================================================================
--- trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolution.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolution.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -316,7 +316,7 @@
     }
 
     // It is possible that the join may have no variables but only if the query returns empty.
-    if (this.result.getRowCardinality() != Cursor.ZERO) {
+    if (!this.result.isEmpty()) {
       Variable[] local = this.getVariables();
       Variable[] join = this.result.getVariables();
       for (int a = 0; a < local.length; a++) {

Modified: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/LocalizedTuples.java
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/LocalizedTuples.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/LocalizedTuples.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -197,6 +197,9 @@
     return answer.getRowExpectedCount();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return answer.isEmpty();
+  }
 
   /**
    * We can't possibly know whether an {@link Answer} column might be

Modified: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SingletonStatements.java
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SingletonStatements.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SingletonStatements.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -157,6 +157,10 @@
     return Cursor.ONE;
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return false;
+  }
+
   public Variable[] getVariables() {
     return variables;
   }

Modified: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/StatementsWrapperResolution.java
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/StatementsWrapperResolution.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/StatementsWrapperResolution.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -220,6 +220,10 @@
     return statements.getRowCount();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return statements.isEmpty();
+  }
+
   public long getRowUpperBound() throws TuplesException {
     return statements.getRowUpperBound();
   }

Modified: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/StatementsWrapperTuples.java
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/StatementsWrapperTuples.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/StatementsWrapperTuples.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -200,6 +200,14 @@
     return statements.getRowCount();
   }
 
+  /* (non-Javadoc)
+   * @see org.mulgara.store.tuples.AbstractTuples#isEmpty()
+   */
+  @Override
+  public boolean isEmpty() throws TuplesException {
+    return statements.isEmpty();
+  }
+
   /**
    * Delegated to the wrapped statements.
    * @throws TuplesException

Modified: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/TripleSetWrapperStatements.java
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/TripleSetWrapperStatements.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/TripleSetWrapperStatements.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -125,6 +125,10 @@
     return triples.size();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return triples.isEmpty();
+  }
+
   public long getRowUpperBound() {
     return triples.size();
   }

Modified: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/TuplesWrapperResolution.java
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/TuplesWrapperResolution.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/TuplesWrapperResolution.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -180,6 +180,13 @@
     return tuples.getRowCardinality();
   }
 
+
+  /* (non-Javadoc)
+   * @see org.mulgara.query.Cursor#isEmpty()
+   */
+  public boolean isEmpty() throws TuplesException {
+    return tuples.isEmpty();
+  }
   /**
    * Accessor for the binding of a given variable within the current product
    * term (row).

Modified: trunk/src/jar/resolver-url/java/org/mulgara/resolver/url/URLStatements.java
===================================================================
--- trunk/src/jar/resolver-url/java/org/mulgara/resolver/url/URLStatements.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/resolver-url/java/org/mulgara/resolver/url/URLStatements.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -282,6 +282,7 @@
       } else {
         // Create a new parser.
         p = new Parser(url, blankNodeMap);
+        p.start();
         newParser = true;
       }
 

Modified: trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/AnswerWrapperRemoteAnswer.java
===================================================================
--- trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/AnswerWrapperRemoteAnswer.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/AnswerWrapperRemoteAnswer.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -287,6 +287,10 @@
     return answer.getRowCardinality();
   }
 
+  public boolean isEmpty() throws TuplesException, RemoteException {
+    return answer.isEmpty();
+  }
+
   /**
    * Free resources associated with this instance.
    *

Modified: trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/AnswerWrapperRemoteAnswerSerialised.java
===================================================================
--- trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/AnswerWrapperRemoteAnswerSerialised.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/AnswerWrapperRemoteAnswerSerialised.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -300,6 +300,10 @@
     return answer.getRowCardinality();
   }
 
+  public boolean isEmpty() throws TuplesException, RemoteException {
+    return answer.isEmpty();
+  }
+
   /**
    * Free resources associated with this instance.
    *

Modified: trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/BlankNodeWrapperAnswer.java
===================================================================
--- trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/BlankNodeWrapperAnswer.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/BlankNodeWrapperAnswer.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -186,6 +186,10 @@
     return answer.getRowCardinality();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return answer.isEmpty();
+  }
+
   public boolean next() throws TuplesException {
     return answer.next();
   }

Modified: trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteAnswer.java
===================================================================
--- trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteAnswer.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteAnswer.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -181,6 +181,8 @@
    * @throws TuplesException Error accessing the underlying data.
    */
   public int getRowCardinality() throws TuplesException, RemoteException;
+  
+  public boolean isEmpty() throws TuplesException, RemoteException;
 
   /**
    * Free resources associated with this instance.

Modified: trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteAnswerWrapperAnswer.java
===================================================================
--- trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteAnswerWrapperAnswer.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteAnswerWrapperAnswer.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -400,6 +400,18 @@
     }
   }
 
+
+  public boolean isEmpty() throws TuplesException {
+    try {
+      waitForPrefetchThread();
+      assert prefetchThread == null || prefetchThread.hasFinished();
+      return remoteAnswer.isEmpty();
+    } catch (RMITimeoutException rmie) {
+      throw new RuntimeException("Timeout waiting on server", rmie);
+    } catch (RemoteException e) {
+      throw new TuplesException("Can't get remote isEmpty", e);
+    }
+  }
   /**
    * Move to the next row.
    *

Modified: trunk/src/jar/store-stringpool-memory/java/org/mulgara/store/stringpool/memory/MemoryStringPoolImpl.java
===================================================================
--- trunk/src/jar/store-stringpool-memory/java/org/mulgara/store/stringpool/memory/MemoryStringPoolImpl.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/store-stringpool-memory/java/org/mulgara/store/stringpool/memory/MemoryStringPoolImpl.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -541,6 +541,13 @@
     /**
      * {@inheritDoc}
      */
+    public boolean isEmpty() throws TuplesException {
+      return set.isEmpty();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public int getColumnIndex(Variable variable) throws TuplesException {
       if (variable == null) {
         throw new IllegalArgumentException("variable is null");

Modified: trunk/src/jar/store-stringpool-xa/java/org/mulgara/store/stringpool/xa/XAStringPoolImpl.java
===================================================================
--- trunk/src/jar/store-stringpool-xa/java/org/mulgara/store/stringpool/xa/XAStringPoolImpl.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/store-stringpool-xa/java/org/mulgara/store/stringpool/xa/XAStringPoolImpl.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -2439,6 +2439,13 @@
                             Cursor.MANY;
       }
 
+      /* (non-Javadoc)
+       * @see org.mulgara.query.Cursor#isEmpty()
+       */
+      public boolean isEmpty() throws TuplesException {
+        return lowAVLNode == null;
+      }
+
       public int getColumnIndex(Variable variable) throws TuplesException {
         if (variable == null) throw new IllegalArgumentException("variable is null");
 

Modified: trunk/src/jar/store-stringpool-xa11/java/org/mulgara/store/stringpool/xa11/XA11StringPoolImpl.java
===================================================================
--- trunk/src/jar/store-stringpool-xa11/java/org/mulgara/store/stringpool/xa11/XA11StringPoolImpl.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/store-stringpool-xa11/java/org/mulgara/store/stringpool/xa11/XA11StringPoolImpl.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -1858,7 +1858,14 @@
         return rowCardinality;
       }
 
+      /* (non-Javadoc)
+       * @see org.mulgara.query.Cursor#isEmpty()
+       */
+      public boolean isEmpty() throws TuplesException {
+        return lowAVLNode == null;
+      }
 
+
       /** @see org.mulgara.store.tuples.Tuples#getColumnIndex(org.mulgara.query.Variable) */
       public int getColumnIndex(Variable variable) throws TuplesException {
         if (variable == null) throw new IllegalArgumentException("variable is null");

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/Assignment.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/Assignment.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/Assignment.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -253,6 +253,14 @@
     return getRowCount();
   }
 
+  /* (non-Javadoc)
+   * @see org.mulgara.store.tuples.AbstractTuples#isEmpty()
+   */
+  @Override
+  public boolean isEmpty() throws TuplesException {
+    return false;
+  }
+
   /**
    * METHOD TO DO
    *

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/Difference.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/Difference.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/Difference.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -189,6 +189,14 @@
   /**
    * {@inheritDoc}
    */
+  public boolean isEmpty() throws TuplesException {
+    return minuend.isEmpty();
+  }
+
+
+  /**
+   * {@inheritDoc}
+   */
   public boolean hasNoDuplicates() throws TuplesException {
     return minuend.hasNoDuplicates();
   }

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/DistinctTuples.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/DistinctTuples.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/DistinctTuples.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -154,6 +154,10 @@
     return operand.getRowExpectedCount();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return operand.isEmpty();
+  }
+
   /**
    * Gets the Variables attribute of the DistinctTuples object
    *

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/EmptyTuples.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/EmptyTuples.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/EmptyTuples.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -135,6 +135,10 @@
     return 0;
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return true;
+  }
+
   /**
    * Empty has no rows that can be unbound.
    *

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/ExpandedProjection.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/ExpandedProjection.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/ExpandedProjection.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -131,6 +131,14 @@
     return operand.getRowExpectedCount();
   }
 
+  public int getRowCardinality() throws TuplesException {
+    return operand.getRowCardinality();
+  }
+
+  public boolean isEmpty() throws TuplesException {
+    return operand.isEmpty();
+  }
+
   /**
    * Gets the Variables attribute of the OrderedProjection object
    * @return The Variables value

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/FilteredTuples.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/FilteredTuples.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/FilteredTuples.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -100,6 +100,13 @@
 
 
   /** {@inheritDoc} */
+  @Override
+  public boolean isEmpty() throws TuplesException {
+    return unfiltered.isEmpty();
+  }
+
+
+  /** {@inheritDoc} */
   public boolean isColumnEverUnbound(int column) throws TuplesException {
     return unfiltered.isColumnEverUnbound(column);
   }

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftFiltered.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftFiltered.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftFiltered.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -157,6 +157,12 @@
   }
 
 
+  /** {@inheritDoc} */
+  public boolean isEmpty() throws TuplesException {
+    return lhs.isEmpty();
+  }
+
+
   /** {@inheritDoc}  Relies on the lhs of the optional. */
   public boolean isColumnEverUnbound(int column) throws TuplesException {
     int nrLeftVars = lhs.getNumberOfVariables();

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoin.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoin.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoin.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -191,6 +191,12 @@
   }
 
 
+  /** {@inheritDoc} */
+  public boolean isEmpty() throws TuplesException {
+    return lhs.isEmpty();
+  }
+
+
   /** {@inheritDoc}  Relies on the lhs of the optional. */
   public boolean isColumnEverUnbound(int column) throws TuplesException {
     int nrLeftVars = lhs.getNumberOfVariables();
@@ -651,6 +657,13 @@
       return wrapped.getRowCount();
     }
 
+    /* (non-Javadoc)
+     * @see org.mulgara.query.Cursor#isEmpty()
+     */
+    public boolean isEmpty() throws TuplesException {
+      return wrapped.isEmpty();
+    }
+
     /** @see org.mulgara.store.tuples.Tuples#getVariables() */
     public Variable[] getVariables() {
       Variable[] vars = wrapped.getVariables();

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/LetTuples.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/LetTuples.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/LetTuples.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -139,6 +139,12 @@
 
 
   /** {@inheritDoc} */
+  public boolean isEmpty() throws TuplesException {
+    return innerTuples.isEmpty();
+  }
+
+
+  /** {@inheritDoc} */
   public boolean isColumnEverUnbound(int column) throws TuplesException {
     return column == lastCol || innerTuples.isColumnEverUnbound(column);
   }

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/LiteralTuples.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/LiteralTuples.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/LiteralTuples.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -179,6 +179,10 @@
     return getRowCount();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return tuples.isEmpty();
+  }
+
   public boolean isColumnEverUnbound(int column) throws TuplesException {
     return columnContainsUnbound[column];
   }

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedAppend.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedAppend.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedAppend.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -212,6 +212,13 @@
     return bound;
   }
 
+  public boolean isEmpty() throws TuplesException {
+    for (Tuples op : operands) {
+      if (!op.isEmpty()) return false;
+    }
+    return true;
+  }
+
   /**
    * A column is unbound if it's unbound in any of the operands.
    */

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedProjection.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedProjection.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedProjection.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -197,6 +197,10 @@
     return operand.getRowExpectedCount();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return operand.isEmpty();
+  }
+
   /**
    * Gets the Variables attribute of the OrderedProjection object
    *

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuples.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuples.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuples.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -245,6 +245,10 @@
     return getRowCount();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return termList.isEmpty();
+  }
+
   /**
   * This method isn't really implemented; it just assumes all columns might be
   * unbound.

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -138,8 +138,8 @@
         closeOperands(operands);
         if (logger.isDebugEnabled()) logger.debug("Returning unconstrained from append.");
         return unconstrained();
-      } else if (operand.getRowCardinality() == Cursor.ZERO) {
-        if (logger.isDebugEnabled()) logger.debug("Ignoring append operand " + operand + " with rowcount = " + operand.getRowCount());
+      } else if (operand.isEmpty()) {
+        if (logger.isDebugEnabled()) logger.debug("Ignoring empty append operand " + operand);
         continue;
       }
 
@@ -217,7 +217,7 @@
         closeOperands(operands);
         if (logger.isDebugEnabled()) logger.debug("Returning unconstrained from append.");
         return unconstrained();
-      } else if (operand.getRowCardinality() == Cursor.ZERO) {
+      } else if (operand.isEmpty()) {
         if (logger.isDebugEnabled()) logger.debug("Ignoring append operand " + operand + " with rowcount = " + operand.getRowCount());
         continue;
       }
@@ -290,8 +290,8 @@
         closeOperands(operands);
         if (logger.isDebugEnabled()) logger.debug("Returning unconstrained from append.");
         return unconstrained();
-      } else if (arg.getRowCardinality() == Cursor.ZERO) {
-        if (logger.isDebugEnabled()) logger.debug("Ignoring append operand " + arg + " with rowcount = " + arg.getRowCount());
+      } else if (arg.isEmpty()) {
+        if (logger.isDebugEnabled()) logger.debug("Ignoring empty append operand " + arg);
         continue;
       }
 
@@ -399,7 +399,7 @@
         throw new TuplesException("Unable to subtract: no common variables.");
       }
       // double check that the variables are not equal
-      if (subtrahend.getRowCardinality() == Cursor.ZERO || minuend.getRowCardinality() == Cursor.ZERO) {
+      if (subtrahend.isEmpty() || minuend.isEmpty()) {
         logger.debug("Found an empty Tuples with bound variables");
         return (Tuples)minuend.clone();
       }
@@ -452,7 +452,7 @@
       // get the matching columns
       Set<Variable> matchingVars = getMatchingVars(standard, optional);
       // check for empty parameters
-      if (standard.getRowCardinality() == Cursor.ZERO && logger.isDebugEnabled()) logger.debug("Nothing to the left of an optional");
+      if (logger.isDebugEnabled() && standard.getRowCardinality() == Cursor.ZERO) logger.debug("Nothing to the left of an optional");
 
       // If the Optional clause does not have matching variables with the LHS
       // then this is the equivalent to a normal join as a cartesian product
@@ -470,7 +470,7 @@
         return append(filteredProduct, invertedStd);
       }
 
-      if (optional.getRowCardinality() == Cursor.ZERO) {
+      if (optional.isEmpty()) {
         // need to return standard, projected out to the extra variables
         if (optional.getNumberOfVariables() == 0) {
           // This may be empty due to having zero rows (since the columns are truncated in this case)
@@ -599,6 +599,8 @@
     Iterator<? extends Tuples> iter = workingSet.iterator();
     while (iter.hasNext()) {
       Tuples tuples = iter.next();
+      
+      if (tuples.isEmpty()) return false;
 
       switch ((int)tuples.getRowCardinality()) {
         case Cursor.ZERO:
@@ -833,7 +835,7 @@
       boolean noVariables = (variableList == null) || (variableList.size() == 0);
       if (tuples.isUnconstrained() || (noVariables && tuples.getRowCardinality() != Cursor.ZERO)) {
         return unconstrained();
-      } else if (tuples.getRowCardinality() == Cursor.ZERO) {
+      } else if (tuples.isEmpty()) {
         return empty();
       }
 
@@ -950,7 +952,7 @@
     if (tuples.getComparator() == null) {
       if (tuples.isUnconstrained()) {
         return TuplesOperations.unconstrained();
-      } else if (tuples.getRowCardinality() == Cursor.ZERO) {
+      } else if (tuples.isEmpty()) {
         tuples = empty();
       } else {
         if (logger.isDebugEnabled()) logger.debug("Sorting " + tuples.getRowCount() + " rows");
@@ -1003,7 +1005,7 @@
       if (tuples.isUnconstrained()) {
         if (logger.isDebugEnabled()) logger.debug("Returning Unconstrained Tuples.");
         return TuplesOperations.unconstrained();
-      } else if (tuples.getRowCardinality() == Cursor.ZERO) {
+      } else if (tuples.isEmpty()) {
         return empty();
       }
 

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnboundJoin.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnboundJoin.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnboundJoin.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -405,6 +405,13 @@
     }
   }
 
+  public boolean isEmpty() throws TuplesException {
+    for (Tuples op : operands) {
+      if (op.isEmpty()) return true;
+    }
+    return false;
+  }
+
   public boolean isColumnEverUnbound(int column) throws TuplesException {
     try {
       return columnEverUnbound[column];

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnconstrainedTuples.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnconstrainedTuples.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnconstrainedTuples.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -138,6 +138,10 @@
     return getRowCount();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return false;
+  }
+
   /**
    * Unconstrained has no columns that can be unbound.
    *

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedAppend.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedAppend.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedAppend.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -234,6 +234,13 @@
     return rowCardinality;
   }
 
+  public boolean isEmpty() throws TuplesException {
+    for (Tuples op : operands) {
+      if (!op.isEmpty()) return false;
+    }
+    return true;
+  }
+
   public boolean isColumnEverUnbound(int column) throws TuplesException {
     assert(operand >= 0) || (operand < operands.length):"No column " +
         column;

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedProjection.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedProjection.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedProjection.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -194,6 +194,10 @@
     return operand.getRowExpectedCount();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return operand.isEmpty();
+  }
+
   /**
    * A column is unbound if it is unbound in the source of the projection.
    */

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/WrappedTuples.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/WrappedTuples.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/WrappedTuples.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -175,6 +175,9 @@
     return tuples.getRowCardinality();
   }
 
+  public boolean isEmpty() throws TuplesException {
+    return tuples.isEmpty();
+  }
 
   /**
    * Gets the Variables attribute of the WrappedTuples object

Modified: trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/HybridTuples.java
===================================================================
--- trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/HybridTuples.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/HybridTuples.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -418,6 +418,11 @@
   }
 
 
+  public boolean isEmpty() throws TuplesException {
+    return getRowCardinality() == Cursor.ZERO;
+  }
+
+
   /**
    * Required by Tuples.
    */

Modified: trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/HybridTuplesFactory.java
===================================================================
--- trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/HybridTuplesFactory.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/HybridTuplesFactory.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -28,10 +28,6 @@
 package org.mulgara.store.xa;
 
 
-// Java 2 standard packages
-import java.io.IOException;
-
-// Locally written packages
 import org.mulgara.query.TuplesException;
 import org.mulgara.store.tuples.DefaultRowComparator;
 import org.mulgara.store.tuples.RowComparator;

Modified: trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/HybridTuplesTest.java
===================================================================
--- trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/HybridTuplesTest.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/HybridTuplesTest.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -31,7 +31,6 @@
 import junit.framework.*;
 
 import java.io.*;
-import java.nio.*;
 
 // Java 2 standard packages
 import java.util.*;
@@ -39,12 +38,10 @@
 import org.apache.log4j.Logger;
 
 // Locally written packages.
-import org.mulgara.query.TuplesException;
 import org.mulgara.query.Variable;
 import org.mulgara.store.tuples.DefaultRowComparator;
 import org.mulgara.store.tuples.LiteralTuples;
 import org.mulgara.store.tuples.RowComparator;
-import org.mulgara.store.tuples.Tuples;
 
 /**
  * Test cases for HybridTuples.
@@ -78,10 +75,8 @@
   private HybridTuples hybridTuples;
   private RowComparator rowComparator;
 
-  private final static Comparator longSingletonArrayComparator =  new Comparator() {
-        public int compare(Object o1, Object o2) {
-          long[] a1 = (long[])o1;
-          long[] a2 = (long[])o2;
+  private final static Comparator<long[]> longSingletonArrayComparator =  new Comparator<long[]>() {
+        public int compare(long[] a1, long[] a2) {
           return a1[0] == a2[0] ? 0 : (a1[0] < a2[0] ? -1 : +1);
         }
       };
@@ -257,7 +252,7 @@
     LiteralTuples tt = new LiteralTuples(new String[] { "test" });
     tt.appendTuple(v);
 
-    ArrayList values = new ArrayList();
+    ArrayList<long[]> values = new ArrayList<long[]>();
     values.add(v);
 
     // iterate over a large enough range to guarantee several blocks
@@ -278,12 +273,12 @@
 
 //    logger.info("LoadSort: Checking Order");
     // check that the order is as expected
-    Iterator it = values.iterator();
+    Iterator<long[]> it = values.iterator();
     int i = 0;
     try {
       while (it.hasNext()) {
         assertEquals("On iteration " + i, hybridTuples.next(), true);
-        v = (long[])it.next();
+        v = it.next();
         i++;
 //        if (i % 10000 == 0) {
 //          logger.info("Checked " + i + " tuples");
@@ -404,8 +399,6 @@
    * @throws Exception EXCEPTION TO DO
    */
   public void testPositioning() throws Exception {
-    Variable x = new Variable("x");
-    Variable y = new Variable("y");
     LiteralTuples tt = new LiteralTuples(new String[] { "x", "y" });
     tt.appendTuple(new long[] { 1, 2 });
     tt.appendTuple(new long[] { 3, 4 });
@@ -459,7 +452,7 @@
     LiteralTuples tt = new LiteralTuples(new String[] { "test" });
 
 
-    ArrayList values = new ArrayList();
+    ArrayList<long[]> values = new ArrayList<long[]>();
 
     long count = 0;
     // iterate over a large enough range to guarantee several blocks
@@ -475,12 +468,12 @@
     hybridTuples.beforeFirst();
 
     // check that the order is as expected
-    Iterator it = values.iterator();
+    Iterator<long[]> it = values.iterator();
     int i = 0;
     try {
       while (it.hasNext()) {
         assertTrue(hybridTuples.next());
-        long[] v = (long[])it.next();
+        long[] v = it.next();
         i++;
         assertEquals("On iteration " + i, v[0], hybridTuples.getColumnValue(0));
       }
@@ -647,6 +640,7 @@
    * @param ft PARAMETER TO DO
    * @throws Exception EXCEPTION TO DO
    */
+  @SuppressWarnings("unused")
   private void dumpFile(HybridTuples ft) throws Exception {
     PrintStream ps = new PrintStream(new FileOutputStream("/tmp/random.dump"));
 

Modified: trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/MemoryCacheLine.java
===================================================================
--- trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/MemoryCacheLine.java	2010-06-10 18:33:12 UTC (rev 1958)
+++ trunk/src/jar/tuples-hybrid/java/org/mulgara/store/xa/MemoryCacheLine.java	2010-06-30 15:58:53 UTC (rev 1959)
@@ -36,6 +36,7 @@
   protected int    width;
   private   long[] pivotTuple;
 
+  @SuppressWarnings("unused")
   private final static Logger logger = Logger.getLogger(MemoryCacheLine.class);
 
 



More information about the Mulgara-svn mailing list