[Mulgara-svn] r909 - trunk/src/jar/resolver-store/java/org/mulgara/resolver/store
pag at mulgara.org
pag at mulgara.org
Thu May 8 00:09:36 UTC 2008
Author: pag
Date: 2008-05-07 17:09:35 -0700 (Wed, 07 May 2008)
New Revision: 909
Modified:
trunk/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreDuplicateResolution.java
Log:
Introduced functionality to work with 2 variables, and not just a single repeated variable. This has been a long-standing bug (mentioned in previous TODO comment). Needed to be fixed now for SPARQL compatibility
Modified: trunk/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreDuplicateResolution.java
===================================================================
--- trunk/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreDuplicateResolution.java 2008-05-08 00:06:50 UTC (rev 908)
+++ trunk/src/jar/resolver-store/java/org/mulgara/resolver/store/StatementStoreDuplicateResolution.java 2008-05-08 00:09:35 UTC (rev 909)
@@ -57,9 +57,7 @@
* so that the graph index it's resolved against can be resolved anew as its
* variables are bound.
*
- * TO DO: Support <code>$p $x $x</code> - i.e. where we have two variables and
- * another variable not a constant. Also, support <code>mulgara:is</code>
- * re-binding.
+ * TO DO: Support <code>mulgara:is</code> re-binding.
*
* @created 2004-08-26
*
@@ -82,6 +80,18 @@
protected static Logger logger = Logger.getLogger(StatementStoreDuplicateResolution.class);
+ /** Indicates ordering by subject */
+ private final static int MASK0 = 1;
+
+ /** Indicates ordering by predicate */
+ private final static int MASK1 = 2;
+
+ /** Indicates ordering by object */
+ private final static int MASK2 = 4;
+
+ /** Indicates ordering by graph */
+ private final static int MASK3 = 8;
+
/**
* The constraint these tuples were generated to satisfy.
*/
@@ -114,6 +124,9 @@
*/
private int[] columnOrder;
+ /** A mapping between the virtual column numbers and the internal column numbers. */
+ private int[] columnMap;
+
private boolean hasNext = false;
private List variableList;
@@ -134,11 +147,13 @@
// Get variable list.
variableList = new LinkedList();
+ Variable[] baseVars = baseTuples.getVariables();
for (int index = 0; index < sameColumns.length; index++) {
- if (sameColumns[index]) {
- variableList.add(baseTuples.getVariables()[index]);
- }
+ if (sameColumns[index]) variableList.add(baseVars[index]);
}
+ // do 1:1 mapping as this is expected in the tests - variable names are not duplicated
+ columnMap = new int[baseVars.length];
+ for (int i = 0; i < columnMap.length; i++) columnMap[i] = i;
// Project for unique variables.
try {
@@ -185,8 +200,18 @@
long object = toGraphTuplesIndex(constraint.getElement(2));
long meta = toGraphTuplesIndex(constraint.getModel());
- // Return the tuples using the s, p, o hints.
- baseTuples = store.findTuples(subject, predicate, object, meta);
+ final long VAR = NodePool.NONE;
+ if (meta != VAR && subject == VAR && predicate == VAR && object == VAR) {
+ // all variables except the graph. Select explicit ordering.
+ int mask = MASK3;
+ if (equalSubject) mask |= MASK0;
+ if (equalPredicate) mask |= MASK1;
+ if (equalObject) mask |= MASK2;
+ baseTuples = store.findTuples(mask, subject, predicate, object, meta);
+ } else {
+ // Return the tuples using the s, p, o hints.
+ baseTuples = store.findTuples(subject, predicate, object, meta);
+ }
// Get the unique values for the multiply constrained column.
variableList = new LinkedList();
@@ -197,25 +222,27 @@
}
uniqueTuples = TuplesOperations.project(baseTuples, variableList);
- // Set the variables.
- Set uniqueVariables = new HashSet();
+ // Create column map.
+ columnOrder = new int[4];
+ int[] inverseColumnOrder = ((StoreTuples)baseTuples).getColumnOrder();
+ for (int index = 0; index < inverseColumnOrder.length; index++) {
+ columnOrder[inverseColumnOrder[index]] = index;
+ }
+
+ // Set the variables. Using an ordered set.
+ Set uniqueVariables = new LinkedHashSet();
+ columnMap = new int[2];
for (int index = 0; index < baseTuples.getVariables().length; index++) {
Object obj = constraint.getElement(index);
if (obj instanceof Variable) {
if (!((Variable) obj).equals(Variable.FROM)) {
+ if (!uniqueVariables.contains(obj)) columnMap[uniqueVariables.size()] = columnOrder[index];
uniqueVariables.add(obj);
}
}
}
- setVariables((Variable[]) uniqueVariables.toArray(new Variable[] {}));
+ setVariables((Variable[]) uniqueVariables.toArray(new Variable[uniqueVariables.size()]));
- // Create column map.
- int[] inverseColumnOrder = ((StoreTuples) baseTuples).getColumnOrder();
- columnOrder = new int[4];
- for (int index = 0; index < inverseColumnOrder.length; index++) {
- columnOrder[inverseColumnOrder[index]] = index;
- }
-
// Set up the tuples evaluator.
setTuplesEvaluator();
}
@@ -308,11 +335,11 @@
}
public long getColumnValue(int column) throws TuplesException {
- return baseTuples.getColumnValue(column);
+ return baseTuples.getColumnValue(columnMap[column]);
}
public boolean isColumnEverUnbound(int column) throws TuplesException {
- return baseTuples.isColumnEverUnbound(column);
+ return baseTuples.isColumnEverUnbound(columnMap[column]);
}
public boolean isUnconstrained() throws TuplesException {
@@ -404,21 +431,37 @@
public void beforeFirst(long[] prefix, int suffixTruncation)
throws TuplesException {
+ // create a new prefix for uniqueTuples
+ // this only includes columns from the initial prefix that represented duplicate variables
+ // takes advantage of the fact that variables came out in the same order as the initial constraint
+ // also, sameColumns offsets are same as baseTuples offsets
+ long[] duplicatesPrefix = new long[] {};
+ for (int i = 0; i < prefix.length; i++) {
+ // i is an index into the virtual tuples. Map it to the original columns
+ if (sameColumns[columnMap[i]]) {
+ // only the first of the duplicated columns was mapped
+ duplicatesPrefix = new long[] { prefix[i], prefix[i] };
+ break;
+ }
+ }
+
// Get the subject/predicate before first.
- uniqueTuples.beforeFirst(prefix, suffixTruncation);
- baseTuples.beforeFirst(prefix, suffixTruncation);
+ uniqueTuples.beforeFirst(duplicatesPrefix, suffixTruncation);
- hasNext = uniqueTuples.next();
- while (hasNext && (uniqueTuples.getColumnValue(0) !=
- uniqueTuples.getColumnValue(1))) {
- hasNext = uniqueTuples.next();
- }
+ hasNext = uniqueTuples.next();
+ while (hasNext && (uniqueTuples.getColumnValue(0) != uniqueTuples.getColumnValue(1))) {
+ hasNext = uniqueTuples.next();
+ }
- // Go to the first tuples.
- if (hasNext) {
- baseTuples.beforeFirst(new long[] { uniqueTuples.getColumnValue(0),
- uniqueTuples.getColumnValue(1) }, 0);
- }
+ // Go to the first tuples. Ignoring suffix truncation.
+ if (hasNext) {
+ if (prefix.length <= 1) {
+ baseTuples.beforeFirst(new long[] { uniqueTuples.getColumnValue(0), uniqueTuples.getColumnValue(1) }, 0);
+ } else {
+ assert prefix.length == 2;
+ baseTuples.beforeFirst(new long[] { uniqueTuples.getColumnValue(0), uniqueTuples.getColumnValue(1), prefix[1] }, 0);
+ }
+ }
}
public boolean next() throws TuplesException {
More information about the Mulgara-svn
mailing list