[Mulgara-svn] r1426 - in branches/xa11/src/jar/resolver-store/java/org/mulgara: resolver/store store/statement/xa store/statement/xa11

pag at mulgara.org pag at mulgara.org
Sat Jan 10 08:10:38 UTC 2009


Author: pag
Date: 2009-01-10 00:10:37 -0800 (Sat, 10 Jan 2009)
New Revision: 1426

Modified:
   branches/xa11/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreResolution.java
   branches/xa11/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreResolver.java
   branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa/TripleAVLFile.java
   branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImpl.java
   branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImplUnitTest.java
   branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImpl.java
   branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImplUnitTest.java
Log:
Commit for partially working XA11 indexing. Some tests still not passing

Modified: branches/xa11/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreResolution.java
===================================================================
--- branches/xa11/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreResolution.java	2009-01-10 08:09:10 UTC (rev 1425)
+++ branches/xa11/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreResolution.java	2009-01-10 08:10:37 UTC (rev 1426)
@@ -40,8 +40,6 @@
 // Locally written packages
 import org.mulgara.query.*;
 import org.mulgara.resolver.spi.ReresolvableResolution;
-import org.mulgara.resolver.spi.Resolution;
-import org.mulgara.resolver.spi.Resolver;
 import org.mulgara.store.nodepool.NodePool;
 import org.mulgara.store.statement.StatementStore;
 import org.mulgara.store.statement.StatementStoreException;
@@ -241,6 +239,7 @@
   /**
    * @param bound constraints to be bound post-beforeFirst.  In constraint-order.
    */
+  @SuppressWarnings("unchecked")
   protected void defineIndex(boolean[] bound) throws TuplesException {
     assert bound.length == 4;
 
@@ -254,8 +253,7 @@
 
     if (indexedTuples != null) {
       if (logger.isDebugEnabled()) {
-        logger.debug("Orig indexedTuples.variables = " +
-                    toString(indexedTuples.getVariables()));
+        logger.debug("Orig indexedTuples.variables = " + toString(indexedTuples.getVariables()));
       }
       indexedTuples.close();
     }
@@ -352,14 +350,14 @@
   }
 
 
-  public ReresolvableResolution reresolve(final Map bindings) throws TuplesException {
+  public ReresolvableResolution reresolve(final Map<? extends ConstraintElement, Long> bindings) throws TuplesException {
     boolean reconstrain = false;
     ConstraintElement[] e = new ConstraintElement[4];
     for (int i = 0; i < 4; i++) {
       e[i] = constraint.getElement(i);
 
       if (e[i] instanceof Variable) {
-        Long value = (Long)bindings.get(e[i]);
+        Long value = bindings.get(e[i]);
         if (value != null) {
           e[i] = new LocalNode(value.longValue());
           reconstrain = true;
@@ -445,8 +443,8 @@
   }
 
 
-  public List getOperands() {
-    return Collections.EMPTY_LIST;
+  public List<Tuples> getOperands() {
+    return Collections.emptyList();
   }
 
 
@@ -557,17 +555,17 @@
     return this;
   }
 
-  public Annotation getAnnotation(Class annotation) {
+  public Annotation getAnnotation(Class<? extends Annotation> annotation) {
     if (annotation.equals(DefinablePrefixAnnotation.class)) {
       return new DefinablePrefixAnnotation() {
-        public void definePrefix(Set boundVars) throws TuplesException {
+        public void definePrefix(Set<Variable> boundVars) throws TuplesException {
           boolean[] bound = new boolean[4];
           Constraint constraint = getConstraint();
           for (int i = 0; i < 4; i++) {
             ConstraintElement elem = constraint.getElement(i);
             if (elem instanceof LocalNode) {
               bound[i] = true;
-            } else if (boundVars.contains((Variable)elem)) {
+            } else if (boundVars.contains(elem)) {
               bound[i] = true;
             } else {
               bound[i] = false;

Modified: branches/xa11/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreResolver.java
===================================================================
--- branches/xa11/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreResolver.java	2009-01-10 08:09:10 UTC (rev 1425)
+++ branches/xa11/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreResolver.java	2009-01-10 08:10:37 UTC (rev 1426)
@@ -131,7 +131,7 @@
   {
     // Validate parameters
     if (modelTypeURI == null) {
-      throw new IllegalArgumentException("Model type can't be Null");
+      throw new IllegalArgumentException("Graph type can't be Null");
     }
     if (statementStore == null) {
       throw new IllegalArgumentException("Null 'statementStore' parameter");
@@ -163,7 +163,7 @@
   {
     // Validate parameters
     if (modelTypeURI == null) {
-      throw new IllegalArgumentException("Model type can't be Null");
+      throw new IllegalArgumentException("Graph type can't be Null");
     }
     if (statementStore == null) {
       throw new IllegalArgumentException("Null 'statementStore' parameter");
@@ -315,7 +315,7 @@
       Node node = resolverSession.globalize(model);
       if (!(node instanceof URIReference)) {
         throw new ResolverException(
-          "Model " + model + " is " + node + ", not a URI reference");
+          "Graph " + model + " is " + node + ", not a URI reference");
       }
       modelURIReference = (URIReference) node;
     } catch (GlobalizeException e) {
@@ -355,7 +355,7 @@
         
         if (occurs) {
           // statement is asserted to be true
-          logger.debug("Inserting statement: [" + subject + " "
+          if (logger.isDebugEnabled()) logger.debug("Inserting statement: [" + subject + " "
                                                 + predicate + " "
                                                 + object + "] in " + model);
 
@@ -524,4 +524,11 @@
     }
   }
 
+  /**
+   * @see org.mulgara.resolver.spi.SystemResolver#initializeSystemNodes(long, long, long)
+   */
+  public void initializeSystemNodes(long systemGraphNode, long rdfTypeNode, long systemGraphTypeNode) {
+    statementStore.initializeSystemNodes(systemGraphNode, rdfTypeNode, systemGraphTypeNode);
+  }
+
 }

Modified: branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa/TripleAVLFile.java
===================================================================
--- branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa/TripleAVLFile.java	2009-01-10 08:09:10 UTC (rev 1425)
+++ branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa/TripleAVLFile.java	2009-01-10 08:10:37 UTC (rev 1426)
@@ -1189,6 +1189,39 @@
     }
 
 
+    public StoreTuples findTuplesForMeta(long graph) throws IOException {
+      long[] startTriple = new long[SIZEOF_TRIPLE];
+      long[] endTriple = new long[SIZEOF_TRIPLE];
+      startTriple[order0] = graph;
+      endTriple[order0] = graph + 1;
+      return new MetaTuplesImpl(startTriple, endTriple, 1);
+    }
+
+
+    public StoreTuples findTuplesForMeta(long graph, long node1) throws IOException {
+      long[] startTriple = new long[SIZEOF_TRIPLE];
+      long[] endTriple = new long[SIZEOF_TRIPLE];
+      startTriple[order0] = graph;
+      startTriple[order1] = node1;
+      endTriple[order0] = graph;
+      endTriple[order1] = node1 + 1;
+      return new MetaTuplesImpl(startTriple, endTriple, 2);
+    }
+
+
+    public StoreTuples findTuplesForMeta(long graph, long node1, long node2) throws IOException {
+      long[] startTriple = new long[SIZEOF_TRIPLE];
+      long[] endTriple = new long[SIZEOF_TRIPLE];
+      startTriple[order0] = graph;
+      startTriple[order1] = node1;
+      startTriple[order2] = node2;
+      endTriple[order0] = graph;
+      endTriple[order1] = node1;
+      endTriple[order2] = node2 + 1;
+      return new MetaTuplesImpl(startTriple, endTriple, 3);
+    }
+
+
     public StoreTuples allTuples() {
       return new TuplesImpl();
     }
@@ -1661,12 +1694,11 @@
     }
 
 
-    private final class TuplesImpl implements StoreTuples {
+    private abstract class AbstractStoreTuples implements StoreTuples {
 
       // keep a stack trace of the instantiation of this object
-      @SuppressWarnings("unused")
-      private StackTrace stack = logger.isDebugEnabled() ? new StackTrace() : null;
-      private List<Integer> objectIds = new ArrayList<Integer>();
+      protected StackTrace stack = logger.isDebugEnabled() ? new StackTrace() : null;
+      protected List<Integer> objectIds = new ArrayList<Integer>();
 
       private long[] startTriple;
 
@@ -1676,7 +1708,7 @@
 
       private TripleLocation end;
 
-      private Token token;
+      protected Token token;
 
       private long nrTriples;
 
@@ -1685,21 +1717,21 @@
       @SuppressWarnings("unused")
       private int prefixLength;
 
-      private int[] columnMap;
+      protected int[] columnMap;
 
-      private Variable[] variables;
+      protected Variable[] variables;
 
       private long[] tmpTriple = new long[SIZEOF_TRIPLE];
 
-      private AVLNode node;
+      protected AVLNode node;
 
-      private boolean beforeStart;
+      protected boolean beforeStart;
 
       private int nrBlockTriples = 0;
 
-      private Block tripleBlock = null;
+      protected Block tripleBlock = null;
 
-      private int offset;
+      protected int offset;
 
       private long endBlockId = Block.INVALID_BLOCK_ID;
 
@@ -1717,7 +1749,7 @@
        * @param prefixLength PARAMETER TO DO
        * @throws IOException EXCEPTION TO DO
        */
-      TuplesImpl(
+      AbstractStoreTuples(
           long[] startTriple, long[] endTriple,
           int prefixLength
       ) throws IOException {
@@ -1737,11 +1769,6 @@
           columnMap[i] = sortOrder[(i + prefixLength) % SIZEOF_TRIPLE];
         }
 
-        variables = new Variable[nrColumns];
-        for (int i = 0; i < nrColumns; ++i) {
-          variables[i] = StatementStore.VARIABLES[columnMap[i]];
-        }
-
         start = findTriple(startTriple);
         end = findTriple(endTriple);
 
@@ -1761,7 +1788,7 @@
       /**
        * CONSTRUCTOR TuplesImpl TO DO
        */
-      TuplesImpl() {
+      AbstractStoreTuples() {
         if (Phase.this == currentPhase && tripleWriteThread != null) tripleWriteThread.drain();
 
         this.nrTriples = Phase.this.nrFileTriples;
@@ -1898,8 +1925,8 @@
       }
 
 
-      public List getOperands() {
-        return new ArrayList(0);
+      public List<Tuples> getOperands() {
+        return Collections.emptyList();
       }
 
 
@@ -2057,7 +2084,7 @@
 
       public Object clone() {
         try {
-          TuplesImpl copy = (TuplesImpl) super.clone();
+          AbstractStoreTuples copy = (AbstractStoreTuples) super.clone();
           tmpTriple = new long[SIZEOF_TRIPLE];
           if (start != null) {
             start.node.incRefCount();
@@ -2220,11 +2247,89 @@
       /**
        * Copied from AbstractTuples
        */
-      public Annotation getAnnotation(Class annotationClass) throws TuplesException {
+      public Annotation getAnnotation(Class<? extends Annotation> annotationClass) throws TuplesException {
         return null;
       }
     }
 
+    /**
+     * The standard implementation of the StoreTuples for this phase.
+     */
+    private final class TuplesImpl extends AbstractStoreTuples {
+      TuplesImpl(long[] startTriple, long[] endTriple, int prefixLength) throws IOException {
+        super(startTriple, endTriple, prefixLength);
+        int nrColumns = SIZEOF_TRIPLE - prefixLength;
+        variables = new Variable[nrColumns];
+        for (int i = 0; i < nrColumns; ++i) {
+          variables[i] = StatementStore.VARIABLES[columnMap[i]];
+        }
+
+      }
+
+      TuplesImpl() {
+        super();
+      }
+    }
+
+    /**
+     * A version of StoreTuples which is designed to set the Meta variable to a requested value.
+     *
+     * @created Dec 22, 2008
+     * @author Paul Gearon
+     * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+     * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+     */
+    private final class MetaTuplesImpl extends AbstractStoreTuples {
+
+      /** The meta node this tuples comes from. */
+      private final long metaNode;
+
+      /**
+       * Constructs the Tuples to come from the store.
+       * @param startTriple The first triple for this tuples.
+       * @param endTriple The first triple pattern that is NOT part of this tuples.
+       *                  This may not appear in the store, but if anything is <= this triple
+       *                  then it is NOT in the tuples.
+       * @param prefixLength The number of elements used to identify the requires triples.
+       * @throws IOException If there was an I/O error accessing the triples data in the store.
+       */
+      MetaTuplesImpl(long[] startTriple, long[] endTriple, int prefixLength) throws IOException {
+        super(startTriple, endTriple, prefixLength);
+        int nrColumns = SIZEOF_TRIPLE - prefixLength;
+        variables = new Variable[nrColumns + 1];
+        for (int i = 0; i < nrColumns; ++i) {
+          variables[i] = StatementStore.VARIABLES[columnMap[i]];
+        }
+        // make the last variable "Meta"
+        variables[nrColumns] = StatementStore.VARIABLES[StatementStore.VARIABLES.length - 1];
+        metaNode = startTriple[order0];
+      }
+
+      /**
+       * Get the value from the given column on the current row.
+       * @param column The column to get the value of the binding from.
+       * @return The binding for the given column on the current row.
+       * @throws TuplesException If the current state is wrong, or if the column requested is invalid.
+       */
+      public long getColumnValue(int column) throws TuplesException {
+        if (column == variables.length - 1) return metaNode;
+        // inlining rather than calling to super
+        try {
+          return tripleBlock.getLong(offset * SIZEOF_TRIPLE + columnMap[column]);
+        } catch (ArrayIndexOutOfBoundsException ex) {
+          if (column < 0 || column >= variables.length) {
+            throw new TuplesException("Column index out of range: " + column);
+          }
+          throw ex;
+        } catch (NullPointerException ex) {
+          if (beforeStart || node == null) {
+            throw new TuplesException("No current row.  Before start: " + beforeStart + " node: " + node);
+          }
+          throw ex;
+        }
+      }
+
+    }
   }
 
 }

Modified: branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImpl.java
===================================================================
--- branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImpl.java	2009-01-10 08:09:10 UTC (rev 1425)
+++ branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImpl.java	2009-01-10 08:10:37 UTC (rev 1426)
@@ -37,7 +37,6 @@
 
 // Locally written packages
 import org.mulgara.query.*;
-import org.mulgara.store.*;
 import org.mulgara.store.nodepool.*;
 import org.mulgara.store.statement.*;
 import org.mulgara.store.tuples.StoreTuples;
@@ -293,7 +292,7 @@
   /**
    * Description of the Field
    */
-  private List releaseNodeListeners = new ArrayList();
+  private List<ReleaseNodeListener> releaseNodeListeners = new ArrayList<ReleaseNodeListener>();
 
   //private XANodePoolImpl nodePool = null;
 
@@ -1148,11 +1147,7 @@
    * @throws Exception EXCEPTION TO DO
    */
   private void notifyReleaseNodeListeners(long node) throws Exception {
-    Iterator it = releaseNodeListeners.iterator();
-    while (it.hasNext()) {
-      ReleaseNodeListener l = (ReleaseNodeListener) it.next();
-      l.releaseNode(node);
-    }
+    for (ReleaseNodeListener l: releaseNodeListeners) l.releaseNode(node);
   }
 
 
@@ -1463,6 +1458,14 @@
     public int getPhaseNumber() {
       return phaseNumber;
     }
+
+
+    /**
+     * Ignored for this implementation.
+     */
+    public void initializeSystemNodes(long systemGraphNode, long rdfTypeNode, long systemGraphTypeNode) {
+      // do nothing
+    }
   }
 
 
@@ -1967,4 +1970,12 @@
 
   }
 
+
+  /**
+   * Ignored for this implementation.
+   */
+  public void initializeSystemNodes(long systemGraphNode, long rdfTypeNode, long systemGraphTypeNode) {
+    // do nothing
+  }
+
 }

Modified: branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImplUnitTest.java
===================================================================
--- branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImplUnitTest.java	2009-01-10 08:09:10 UTC (rev 1425)
+++ branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImplUnitTest.java	2009-01-10 08:10:37 UTC (rev 1426)
@@ -39,6 +39,7 @@
 // locally written packages
 import org.mulgara.store.nodepool.*;
 import org.mulgara.store.statement.*;
+import org.mulgara.store.tuples.TestTuples;
 import org.mulgara.util.*;
 
 
@@ -195,4 +196,21 @@
     }
     super.tearDown();
   }
+
+  
+  /**
+   * Return a dump of all tuples, sorted by the primary index: 0123.
+   * @see org.mulgara.store.statement.StatementStoreAbstractUnitTest#getDump()
+   */
+  protected TestTuples getDump() {
+    TestTuples expected = new TestTuples();
+    add(expected, StatementStore.VARIABLES, new long[] {1, 2, 3, 1});
+    add(expected, StatementStore.VARIABLES, new long[] {1, 2, 4, 2});
+    add(expected, StatementStore.VARIABLES, new long[] {1, RDF_TYPE, GRAPH_TYPE, SYSTEM_GRAPH});
+    add(expected, StatementStore.VARIABLES, new long[] {2, 5, 6, 2});
+    add(expected, StatementStore.VARIABLES, new long[] {2, RDF_TYPE, GRAPH_TYPE, SYSTEM_GRAPH});
+    add(expected, StatementStore.VARIABLES, new long[] {SYSTEM_GRAPH, RDF_TYPE, GRAPH_TYPE, SYSTEM_GRAPH});
+    return expected;
+  }
+
 }

Modified: branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImpl.java
===================================================================
--- branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImpl.java	2009-01-10 08:09:10 UTC (rev 1425)
+++ branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImpl.java	2009-01-10 08:10:37 UTC (rev 1426)
@@ -141,6 +141,15 @@
   /** The mask for a bound Graph. This must always be set. */
   private final static int MASK3 = 8;
 
+  /** The node number for the system graph. Globalized to <#>. */
+  private long systemGraphNode = NONE;
+
+  /** The node number for <rdf:type>. */
+  private long rdfTypeNode = NONE;
+
+  /** The node number for the graph class <mulgara:ModelType>. */
+  private long graphTypeNode = NONE;
+
   /** The name of the triple store which forms the base name for the graph files. */
   private String fileName;
 
@@ -188,6 +197,9 @@
   /** A reference token for keeping the recording phase available until we no longer need it */
   private Phase.Token recordingPhaseToken = null;
 
+  /** The list of graphs known to this statement store. */
+  private List<Long> committedGraphNodes;
+
   /**
    * This flag indicates that the current object has been fully written, and may be considered
    * as committed when the rest of the system is ready.
@@ -451,7 +463,6 @@
    * @throws StatementStoreException if something exceptional happens
    */
   public synchronized StoreTuples findTuples(boolean node0Bound, boolean node1Bound, boolean node2Bound, boolean node3Bound) throws StatementStoreException {
-    if (!node3Bound) throw new IllegalArgumentException("The graph must be bound");
     checkInitialized();
     dirty = false;
     return currentPhase.findTuples(node0Bound, node1Bound, node2Bound);
@@ -715,6 +726,7 @@
       synchronized (committedPhaseLock) {
         if (committedPhaseToken != null) committedPhaseToken.release();
         committedPhaseToken = recordingPhaseToken;
+        committedGraphNodes = currentPhase.graphNodes;
       }
       recordingPhaseToken = null;
     } catch (IOException ex) {
@@ -1156,6 +1168,14 @@
     public int getPhaseNumber() {
       return phaseNumber;
     }
+
+
+    /**
+     * Not used on a read-only graph
+     */
+    public void initializeSystemNodes(long systemGraphNode, long rdfTypeNode, long systemGraphTypeNode) {
+      // do nothing
+    }
   }
 
 
@@ -1171,7 +1191,10 @@
     /** Maintaines parallel structural phases between all of the parallel tree data structures */
     private TripleAVLFile.Phase[] tripleAVLFilePhases = new TripleAVLFile.Phase[NR_INDEXES];
 
+    /** The list of graphs valid in this phase. */
+    private List<Long> graphNodes = null;
 
+
     /**
      * Creates a new phase based on the current state of the database.
      * This sets the latest phase on the outer statement store.
@@ -1181,6 +1204,11 @@
       for (int i = 0; i < NR_INDEXES; ++i) tripleAVLFilePhases[i] = tripleAVLFiles[i].new Phase();
       currentPhase = this;
       dirty = true;
+      try {
+        graphNodes = committedGraphNodes == null ? scanForGraphs() : new ArrayList<Long>(committedGraphNodes);
+      } catch (StatementStoreException e) {
+        throw new IOException("Unable to get metadata for phase: " + e.getMessage());
+      }
     }
 
 
@@ -1195,6 +1223,7 @@
       for (int i = 0; i < NR_INDEXES; ++i) tripleAVLFilePhases[i] = tripleAVLFiles[i].new Phase(p.tripleAVLFilePhases[i]);
       currentPhase = this;
       dirty = true;
+      graphNodes = new ArrayList<Long>(p.graphNodes);
     }
 
 
@@ -1211,6 +1240,11 @@
       }
       currentPhase = this;
       dirty = false;
+      try {
+        graphNodes = scanForGraphs();
+      } catch (StatementStoreException sse) {
+        throw new IOException("Error accessing graph data during initialization");
+      }
     }
 
 
@@ -1306,6 +1340,8 @@
       long[] triple = new long[]{node0, node1, node2, node3};
 
       for (int i = 0; i < NR_INDEXES; ++i) tripleAVLFilePhases[i].asyncAddTriple(triple);
+
+      if (node1 == rdfTypeNode && node2 == graphTypeNode && node3 == systemGraphNode) graphNodes.add(node0);
     }
 
 
@@ -1333,6 +1369,7 @@
       } catch (IOException e) {
         throw new StatementStoreException("I/O error", e);
       }
+      if (node1 == rdfTypeNode && node2 == graphTypeNode && node3 == systemGraphNode) graphNodes.remove(node0);
     }
 
 
@@ -1412,7 +1449,7 @@
         (node3 != NONE ? MASK3 : 0);
 
       if (node3 == NONE && variableMask != 0) {
-        throw new IllegalArgumentException("Graph must be specified");
+        return joinGraphedTuples(variableMask, node0, node1, node2);
       }
 
 
@@ -1435,7 +1472,7 @@
           case MASK1 | MASK2 | MASK3:
             return tripleAVLFilePhases[TI_3120].findTuples(node3, node1, node2);
           case MASK0 | MASK1 | MASK2 | MASK3:
-            if (tripleAVLFilePhases[TI_3012].existsTriple(node0, node1, node2, node3)) {
+            if (tripleAVLFilePhases[TI_3012].existsTriple(node3, node0, node1, node2)) {
               return TuplesOperations.unconstrained();
             }
             return TuplesOperations.empty();
@@ -1459,6 +1496,59 @@
     }
 
 
+    StoreTuples joinGraphedTuples(int variableMask, long node0, long node1, long node2) throws StatementStoreException {
+      try {
+        assert (variableMask & MASK3) == 0 : "Must not be asking to join on multiple graphs unless graph is variable.";
+
+        // get the graphNodes if not already configured
+        if (graphNodes.isEmpty()) throw new IllegalStateException("Unable to query for variable graphs until graphs are initialized");
+
+        ArrayList<StoreTuples> graphedTuples = new ArrayList<StoreTuples>();
+        for (long graphNode: graphNodes) {
+          StoreTuples partialResult = null;
+          switch (variableMask) {
+            case 0:
+              partialResult = tripleAVLFilePhases[TI_3012].findTuplesForMeta(graphNode);
+              break;
+            case MASK0:
+              partialResult = tripleAVLFilePhases[TI_3012].findTuplesForMeta(graphNode, node0);
+              break;
+            case MASK1:
+              partialResult = tripleAVLFilePhases[TI_3120].findTuplesForMeta(graphNode, node1);
+              break;
+            case MASK0 | MASK1:
+              partialResult = tripleAVLFilePhases[TI_3012].findTuplesForMeta(graphNode, node0, node1);
+              break;
+            case MASK2:
+              partialResult = tripleAVLFilePhases[TI_3201].findTuplesForMeta(graphNode, node2);
+              break;
+            case MASK0 | MASK2:
+              partialResult = tripleAVLFilePhases[TI_3201].findTuplesForMeta(graphNode, node2, node0);
+              break;
+            case MASK1 | MASK2:
+              partialResult = tripleAVLFilePhases[TI_3120].findTuplesForMeta(graphNode, node1, node2);
+              break;
+            case MASK0 | MASK1 | MASK2:
+              if (tripleAVLFilePhases[TI_3012].existsTriple(node0, node1, node2, graphNode)) {
+                // TODO: convert this to a literal tuples TestTuples(node1, node1, node2, graphNode)
+                partialResult = TuplesOperations.unconstrained();
+              } else {
+                partialResult = TuplesOperations.empty();
+              }
+              break;
+            default:
+              throw new AssertionError("Search structure incorrectly calculated");
+          }
+          graphedTuples.add(partialResult);
+        }
+        return TuplesOperations.appendCompatible(graphedTuples);
+      } catch (TuplesException te) {
+        throw new StatementStoreException("Error accessing Tuples", te);
+      } catch (IOException ex) {
+        throw new StatementStoreException("I/O error", ex);
+      }
+    }
+
     /**
      * Test is there exist triples according to a given pattern
      * @param node0 A subject gNode, or NONE
@@ -1537,6 +1627,29 @@
 
 
     /**
+     * Ask the system for all the known graphs.
+     * @return All the known graph nodes.
+     */
+    List<Long> scanForGraphs() throws StatementStoreException, IOException {
+      List<Long> nodeList = new ArrayList<Long>();
+
+      if (systemGraphNode == NONE || rdfTypeNode == NONE || graphTypeNode == NONE) return nodeList;
+
+      StoreTuples graphTuples = tripleAVLFilePhases[TI_3120].findTuples(systemGraphNode, rdfTypeNode, graphTypeNode);
+      assert graphTuples.getNumberOfVariables() == 1;
+
+      try {
+        graphTuples.beforeFirst();
+        while (graphTuples.next()) nodeList.add(graphTuples.getColumnValue(0));
+      } catch (TuplesException e) {
+        throw new StatementStoreException("Unable to construct a result containing all graphs.", e);
+      }
+
+      return nodeList;
+    }
+
+
+    /**
      * Increment the reference count on this object.
      * @return A new token representing the reference.
      */
@@ -1591,4 +1704,32 @@
 
   }
 
+
+  /**
+   * @see org.mulgara.store.xa.XAStatementStore#initializeSystemNodes(long, long, long)
+   * Set the various system graph nodes. These may only be set once, but will allow duplicate calls if the values are the same.
+   * @param systemGraphNode The new system graph node.
+   * @param rdfTypeNode The node for <rdf:graph>.
+   * @param systemGraphTypeNode The node for the system graph type.
+   */
+  public void initializeSystemNodes(long systemGraphNode, long rdfTypeNode, long systemGraphTypeNode) {
+    if (this.systemGraphNode != NONE && systemGraphNode != this.systemGraphNode) {
+      throw new IllegalStateException("Cannot set system graph again. Was: " + this.systemGraphNode + ", now: " + systemGraphNode);
+    }
+    if (systemGraphNode < 0) throw new IllegalArgumentException("Attempt to set invalid system graph node");
+    this.systemGraphNode = systemGraphNode;
+
+    if (this.rdfTypeNode != NONE && rdfTypeNode != this.rdfTypeNode) {
+      throw new IllegalStateException("Cannot set the rdf:type node again. Was: " + this.rdfTypeNode + ", now: " + rdfTypeNode);
+    }
+    if (rdfTypeNode < 0) throw new IllegalArgumentException("Attempt to set invalid rdf:type node");
+    this.rdfTypeNode = rdfTypeNode;
+
+    if (this.graphTypeNode != NONE && systemGraphTypeNode != this.graphTypeNode) {
+      throw new IllegalStateException("Cannot set graph type again. Was: " + this.graphTypeNode + ", now: " + systemGraphTypeNode);
+    }
+    if (systemGraphTypeNode < 0) throw new IllegalArgumentException("Attempt to set invalid graph type node");
+    this.graphTypeNode = systemGraphTypeNode;
+  }
+
 }

Modified: branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImplUnitTest.java
===================================================================
--- branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImplUnitTest.java	2009-01-10 08:09:10 UTC (rev 1425)
+++ branches/xa11/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImplUnitTest.java	2009-01-10 08:10:37 UTC (rev 1426)
@@ -37,6 +37,7 @@
 
 // locally written packages
 import org.mulgara.store.statement.*;
+import org.mulgara.store.tuples.TestTuples;
 import org.mulgara.util.*;
 
 
@@ -146,4 +147,20 @@
     }
     super.tearDown();
   }
+
+  /**
+   * Return a dump of all tuples, sorted by the primary index: 3012.
+   * @see org.mulgara.store.statement.StatementStoreAbstractUnitTest#getDump()
+   */
+  protected TestTuples getDump() {
+    TestTuples expected = new TestTuples();
+    add(expected, StatementStore.VARIABLES, new long[] {1, 2, 3, 1});
+    add(expected, StatementStore.VARIABLES, new long[] {1, 2, 4, 2});
+    add(expected, StatementStore.VARIABLES, new long[] {2, 5, 6, 2});
+    add(expected, StatementStore.VARIABLES, new long[] {1, RDF_TYPE, GRAPH_TYPE, SYSTEM_GRAPH});
+    add(expected, StatementStore.VARIABLES, new long[] {2, RDF_TYPE, GRAPH_TYPE, SYSTEM_GRAPH});
+    add(expected, StatementStore.VARIABLES, new long[] {SYSTEM_GRAPH, RDF_TYPE, GRAPH_TYPE, SYSTEM_GRAPH});
+    return expected;
+  }
+
 }




More information about the Mulgara-svn mailing list