Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: afs/AFS-Dev
base: 0f5a27541f
...
head fork: afs/AFS-Dev
compare: 25e61424f0
  • 2 commits
  • 3 files changed
  • 0 commit comments
  • 1 contributor
Commits on Apr 08, 2012
Andy Seaborne MergeJoin / execution aa29724
Andy Seaborne Refine. 25e6142
View
290 src/main/java/projects/merge/Main.java
@@ -18,32 +18,37 @@
package projects.merge;
-import static projects.merge.ColNames.O ;
-import static projects.merge.ColNames.P ;
-import static projects.merge.ColNames.S ;
-
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.Iterator ;
import java.util.List ;
-import org.openjena.atlas.iterator.Iter ;
-import org.openjena.atlas.lib.ColumnMap ;
+import org.openjena.atlas.lib.StrUtils ;
import org.openjena.atlas.lib.Tuple ;
import org.openjena.atlas.logging.Log ;
-import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.Graph ;
import com.hp.hpl.jena.graph.Triple ;
+import com.hp.hpl.jena.query.ResultSet ;
+import com.hp.hpl.jena.query.ResultSetFactory ;
+import com.hp.hpl.jena.query.ResultSetFormatter ;
import com.hp.hpl.jena.sparql.algebra.Op ;
+import com.hp.hpl.jena.sparql.algebra.OpVars ;
import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.engine.ExecutionContext ;
+import com.hp.hpl.jena.sparql.engine.QueryIterator ;
import com.hp.hpl.jena.sparql.engine.binding.Binding ;
+import com.hp.hpl.jena.sparql.engine.iterator.QueryIterPlainWrapper ;
+import com.hp.hpl.jena.sparql.engine.iterator.QueryIterRoot ;
+import com.hp.hpl.jena.sparql.engine.main.QC ;
import com.hp.hpl.jena.sparql.sse.SSE ;
import com.hp.hpl.jena.tdb.StoreConnection ;
+import com.hp.hpl.jena.tdb.TDB ;
import com.hp.hpl.jena.tdb.base.file.Location ;
import com.hp.hpl.jena.tdb.index.TupleIndex ;
-import com.hp.hpl.jena.tdb.lib.TupleLib ;
import com.hp.hpl.jena.tdb.nodetable.NodeTable ;
import com.hp.hpl.jena.tdb.solver.BindingNodeId ;
+import com.hp.hpl.jena.tdb.solver.SolverLib ;
import com.hp.hpl.jena.tdb.store.DatasetGraphTDB ;
import com.hp.hpl.jena.tdb.store.NodeId ;
import com.hp.hpl.jena.tdb.sys.SetupTDB ;
@@ -52,233 +57,94 @@
{
public static void main(String ... argv)
{
+ // TODO
+ // tests
+ // "Explain" functionality.
+
// Setup
Log.setLog4j() ;
- //ColumnMap colMap = new ColumnMap("SPO", "POS") ;
-
- if ( false )
- {
- ColumnMap colMap = new ColumnMap("POS", Arrays.asList(S,P,O), Arrays.asList(P,O,S)) ;
- Tuple<ColNames> primary = Tuple.create(S,P,O) ;
- System.out.println(colMap.map(primary)) ;
- System.exit(0) ;
- }
-
// Fake the dataset.
- //BasicPattern bgp = SSE.parseBGP("((?s :p ?o) ( ?s :q ?z))") ;
- Op op = SSE.parseOp("(bgp (?s :p ?o) ( ?s :q ?z))") ;
-
DatasetGraphTDB dsg = StoreConnection.make(Location.mem()).getBaseDataset() ;
-
- // Fix up
+ // -- Fix up
Location loc = Location.mem() ;
- TupleIndex POS = SetupTDB.makeTupleIndex(loc, "SPO", "POS", "POS", 3*NodeId.SIZE) ;
TupleIndex PSO = SetupTDB.makeTupleIndex(loc, "SPO", "PSO", "PSO", 3*NodeId.SIZE) ;
TupleIndex[] indexes = dsg.getTripleTable().getNodeTupleTable().getTupleTable().getIndexes() ;
-
- //indexes[0] = SetupTDB.makeTupleIndex(loc, "SPO", "POS", "POS", 3*NodeId.SIZE) ;
- indexes[1] = POS ;
+
+ TupleIndex SPO = indexes[0] ;
+ TupleIndex POS = indexes[1] ;
+ TupleIndex OSP = indexes[2] ;
+
indexes[2] = PSO ;
+
NodeTable nodeTable = dsg.getTripleTable().getNodeTupleTable().getNodeTable() ;
- System.out.println("== Data") ;
- List<String> $ = Arrays.asList(
- "(<s> <p> '1')",
- "(<s1> <p> '3')",
- //"(<s1> <p> '4')",
- "(<s> <q> '5')",
- "(<s1> <q> '6')" ,
- "(<s> <p> '2')"
+
+ //System.out.println("== Data") ;
+ // -- Data
+ String $ = StrUtils.strjoinNL(
+ "(graph",
+ " (<s> <p> '1')",
+ " (<s1> <p> '3')",
+ " (<s1> <p> '4')",
+ " (<s> <q> '5')",
+ " (<s1> <q> '6')" ,
+ " (<s> <p> '6')" ,
+ " (<s> <p> <s>)" ,
+ ")"
) ;
- for ( String s : $ )
- dsg.getDefaultGraph().add(SSE.parseTriple(s)) ;
- //System.out.println(dsg) ;
+ Graph g = SSE.parseGraph($) ;
+ dsg.getDefaultGraph().getBulkUpdateHandler().add(g) ;
+ // This is the triple access
- //Iter.print(nodeTable.all()) ;
- //System.out.println(dsg) ;
- //System.exit(0) ;
-
- if ( false )
+ if ( true )
{
- System.out.println("== Access 1") ;
- // This is the triple access
- Triple triple = SSE.parseTriple("(?s <p> ?o)") ;
-
- // Convert triple to NodeIds or NodeId.ANY.
- Tuple<NodeId> tuple = OpExecutorMerge.convert(nodeTable, triple.getSubject(), triple.getPredicate(), triple.getObject()) ;
- //System.out.println(tuple) ;
-
- // action.
- MergeActionVarIdx action = MergeLib.calcMergeAction(Var.alloc("s"), triple, indexes) ;
+ TupleIndex[] indexes1 = { PSO } ;
+ Triple triple = SSE.parseTriple("(?x <p> ?x)") ; // SPO/?p => no action found. OSP/?x -> wrong.
+ MergeActionVarIdx action = MergeLib.calcMergeAction(Var.alloc("x"), triple, indexes1) ;
System.out.println(action) ;
+ TupleIndex index = action.getIndexAccess().getIndex() ;
- TupleIndex tupleIndex = action.getIndexAccess().getIndex() ;
-
- // access the index for a ann with this prefix.
- // (It will do a partial scan if a trailing constant is set).
- Iterator<Tuple<NodeId>> iter = tupleIndex.find(tuple) ;
- List<Tuple<NodeId>> x = Iter.toList(iter) ;
- System.out.println( Iter.asString(x.iterator(), "\n" ) ) ;
-
- Iterator<Tuple<Node>> iter2 = TupleLib.convertToNodes(nodeTable, x.iterator()) ;
-
- System.out.println( Iter.asString(iter2, "\n" ) ) ;
- }
-
- System.out.println("== Access 2") ;
- // This is the triple access
- Triple triple1 = SSE.parseTriple("(?s <p> ?o)") ;
- Triple triple2 = SSE.parseTriple("(?s <q> ?v)") ;
- Tuple<NodeId> tuple1 = OpExecutorMerge.convert(nodeTable, triple1) ;
- Tuple<NodeId> tuple2 = OpExecutorMerge.convert(nodeTable, triple2) ;
- Tuple<Var> vars1 = OpExecutorMerge.vars(triple1) ;
- Tuple<Var> vars2 = OpExecutorMerge.vars(triple2) ;
-
-
- MergeActionIdxIdx action = MergeLib.calcMergeAction(triple1, triple2, indexes) ;
- Iterator<BindingNodeId> iter = merge(action, tuple1, vars1, tuple2, vars2) ;
- Iter.print(iter) ;
-
-
-
-
-// ExecutionContext eCxt = new ExecutionContext(TDB.getContext(), dsg.getDefaultGraph(), dsg, OpExecutorMerge.factory) ;
-//
-// OpExecutor opExec = OpExecutorMerge.factory.create(eCxt) ;
-// opExec.executeOp(op, QueryIterRoot.create(eCxt)) ;
-
- System.out.println("DONE") ;
-
- }
-
- private static Iterator<BindingNodeId> merge(MergeActionIdxIdx action,
- Tuple<NodeId> tuple1, Tuple<Var> vars1,
- Tuple<NodeId> tuple2, Tuple<Var> vars2)
- {
- int len1 = action.getIndexAccess1().getPrefixLen() ;
- int len2 = action.getIndexAccess2().getPrefixLen() ;
-
- TupleIndex tupleIndex1 = action.getIndexAccess1().getIndex() ;
- TupleIndex tupleIndex2 = action.getIndexAccess2().getIndex() ;
-
- ColumnMap map1 = tupleIndex1.getColumnMap() ;
- ColumnMap map2 = tupleIndex2.getColumnMap() ;
+ Tuple<NodeId> tuple = OpExecutorMerge.convert(nodeTable, triple) ;
+ Tuple<Var> vars = OpExecutorMerge.vars(triple) ;
- Iterator<Tuple<NodeId>> iter1 = tupleIndex1.find(tuple1) ;
- System.out.println("-- Left:") ;
- Iter.print(iter1) ;
- iter1 = tupleIndex1.find(tuple1) ;
-
- Iterator<Tuple<NodeId>> iter2 = tupleIndex2.find(tuple2) ;
- System.out.println("-- Right:") ;
- Iter.print(iter2) ;
- iter2 = tupleIndex2.find(tuple2) ;
- System.out.println("----") ;
- Tuple<NodeId> row1 = null ;
- Tuple<NodeId> row2 = null ;
-
- List<BindingNodeId> results = new ArrayList<>() ;
- List<Tuple<NodeId>> tmp1 = new ArrayList<>() ;
- List<Tuple<NodeId>> tmp2 = new ArrayList<>() ;
-
- for(;;)
- {
- if ( row1 == null )
- {
- if ( ! iter1.hasNext() )
- break ;
- row1 = iter1.next() ;
- }
- if ( row2 == null )
- {
- if ( ! iter2.hasNext() )
- break ;
- row2 = iter2.next() ;
- }
-
- NodeId join1 = tupleIndex1.getColumnMap().fetchSlot(len1, row1) ;
- NodeId join2 = tupleIndex2.getColumnMap().fetchSlot(len2, row2) ;
+ Iterator<Tuple<NodeId>> iter = index.find(tuple) ;
+ List<BindingNodeId> r = new ArrayList<>() ;
- long v1 = join1.getId() ;
- long v2 = join2.getId() ;
-
- if ( v1 == v2 )
- {
- long v = v1 ;
- row1 = advance(v, tupleIndex1, len1, iter1, tmp1, row1) ;
- row2 = advance(v, tupleIndex2, len2, iter2, tmp2, row2) ;
- join(results, action.getVar(), map1, vars1, tmp1, map2, vars2, tmp2) ;
- }
- else if ( v1 > v2 )
- {
- row2 = null ;
- }
- else
- {
- // v1 < v2
- row1 = null ;
- }
- }
- return results.iterator() ;
- }
-
- private static Tuple<NodeId> advance(long v, TupleIndex tupleIndex , int len , Iterator<Tuple<NodeId>> iter, List<Tuple<NodeId>> acc, Tuple<NodeId> row)
- {
- for (;;)
- {
- // Overshoot :-(
- long v1 = tupleIndex.getColumnMap().fetchSlot(len, row).getId() ;
- if ( v != v1 )
- break ;
- acc.add(row) ;
- if ( ! iter.hasNext() )
- return null ;
- row = iter.next() ;
- }
- return row ;
- }
-
- private static void join(List<BindingNodeId> results, Var joinVar,
- ColumnMap map1, Tuple<Var> vars1 , List<Tuple<NodeId>> tmp1,
- ColumnMap map2, Tuple<Var> vars2 , List<Tuple<NodeId>> tmp2)
- {
- System.out.println("join left="+tmp1.size()+" right="+tmp2.size()) ;
- for ( Tuple<NodeId> row1 : tmp1 )
- for ( Tuple<NodeId> row2 : tmp2 )
+ for ( ; iter.hasNext() ; )
{
- System.out.println("Join: "+row1+" "+row2) ;
+ Tuple<NodeId> row = iter.next() ;
+ // Library ise.
BindingNodeId b = new BindingNodeId((Binding)null) ;
- bind(b, joinVar, map1, row1, vars1) ;
- bind(b, joinVar, map2, row2, vars2) ;
- results.add(b) ;
+ b = OpExecutorMerge.bind(b, null, row, vars) ;
+ if ( b != null )
+ r.add(b) ;
}
- tmp1.clear() ;
- tmp2.clear() ;
- }
+ Iterator<Binding> iter2 = SolverLib.convertToNodes(r.iterator(), nodeTable) ;
+ QueryIterator qIter = new QueryIterPlainWrapper(iter2) ;
+ List<String> varNames = Arrays.asList("x") ;
+ ResultSet rs = ResultSetFactory.create(qIter, varNames) ;
+ ResultSetFormatter.out(rs) ;
+ System.out.println("DONE") ;
+ System.exit(0) ;
+ }
- private static void bind(BindingNodeId b, Var joinVar, ColumnMap map, Tuple<NodeId> row, Tuple<Var> vars)
- {
- System.out.println("Bind: "+vars+" "+row+ " "+map) ;
+ // -- Execute
+ ExecutionContext execCxt = new ExecutionContext(TDB.getContext(),
+ dsg.getDefaultGraph(),
+ dsg,
+ OpExecutorMerge.factory
+ ) ;
+ //Op op = SSE.parseOp("(bgp (?s <p> ?o) (?s <q> ?v))") ;
+ Op op = SSE.parseOp("(bgp (?s1 <p> ?o) (<s1> <q> ?o))") ;
- for ( int i = 0 ; i < vars.size() ; i++ )
- {
- int j = map.mapSlotIdx(i) ;
- Var v = vars.get(j) ;
- if ( v == null )
- continue ;
- NodeId id = row.get(j) ;
- b.put(v, id) ;
+ QueryIterator qIter = QC.execute(op, QueryIterRoot.create(execCxt), execCxt) ;
+
+ // -- Results.
+ List<String> varNames = Var.varNames(OpVars.patternVars(op)) ;
+ ResultSet rs = ResultSetFactory.create(qIter, varNames) ;
+ ResultSetFormatter.out(rs) ;
- // Why is this wrong?
-// Var v = vars.get(i) ;
-// if ( v == null )
-// continue ;
-// NodeId id = map.fetchSlot(i, row) ;
-// b.put(v, id) ;
- }
+ System.out.println("DONE") ;
}
-
-
-
}
View
217 src/main/java/projects/merge/OpExecutorMerge.java
@@ -18,9 +18,11 @@
package projects.merge;
+import java.util.ArrayList ;
import java.util.Iterator ;
import java.util.List ;
+import org.openjena.atlas.iterator.Iter ;
import org.openjena.atlas.lib.Tuple ;
import com.hp.hpl.jena.graph.Node ;
@@ -29,11 +31,15 @@
import com.hp.hpl.jena.sparql.core.BasicPattern ;
import com.hp.hpl.jena.sparql.core.Var ;
import com.hp.hpl.jena.sparql.engine.ExecutionContext ;
+import com.hp.hpl.jena.sparql.engine.QueryIterator ;
+import com.hp.hpl.jena.sparql.engine.binding.Binding ;
+import com.hp.hpl.jena.sparql.engine.iterator.QueryIterPlainWrapper ;
import com.hp.hpl.jena.sparql.engine.main.OpExecutor ;
import com.hp.hpl.jena.sparql.engine.main.OpExecutorFactory ;
import com.hp.hpl.jena.tdb.index.TupleIndex ;
import com.hp.hpl.jena.tdb.nodetable.NodeTable ;
import com.hp.hpl.jena.tdb.solver.BindingNodeId ;
+import com.hp.hpl.jena.tdb.solver.SolverLib ;
import com.hp.hpl.jena.tdb.store.DatasetGraphTDB ;
import com.hp.hpl.jena.tdb.store.NodeId ;
@@ -51,6 +57,29 @@ public OpExecutorMerge(ExecutionContext execCxt)
super(execCxt) ;
}
+ @Override
+ protected QueryIterator execute(OpBGP opBGP, QueryIterator input)
+ {
+ BasicPattern bgp = opBGP.getPattern() ;
+ List<Triple> triples = bgp.getList() ;
+
+ if (triples.size() == 0 )
+ {}
+ if (triples.size() == 1 )
+ {}
+
+ DatasetGraphTDB dsg = (DatasetGraphTDB)(execCxt.getDataset()) ;
+
+ NodeTable nodeTable = dsg.getTripleTable().getNodeTupleTable().getNodeTable() ;
+ Triple triple1 = triples.get(0) ;
+ Triple triple2 = triples.get(1) ;
+ TupleIndex[] indexes = dsg.getTripleTable().getNodeTupleTable().getTupleTable().getIndexes() ;
+
+ Iterator<BindingNodeId> iter1 = mergeJoin(triple1, triple2, nodeTable, indexes) ;
+ Iterator<Binding> iter2 = SolverLib.convertToNodes(iter1, nodeTable) ;
+ return new QueryIterPlainWrapper(iter2, execCxt) ;
+ }
+
// (real) default graph only for now.
public Iterator<BindingNodeId> execute(OpBGP opBGP, DatasetGraphTDB dsg)
{
@@ -69,77 +98,157 @@ public OpExecutorMerge(ExecutionContext execCxt)
Triple triple1 = triples.get(0) ;
Triple triple2 = triples.get(1) ;
TupleIndex[] indexes = dsg.getTripleTable().getNodeTupleTable().getTupleTable().getIndexes() ;
- MergeActionIdxIdx action = MergeLib.calcMergeAction(triple1, triple2, indexes) ;
- if ( action == null )
- {}
-
- // perform action in NodeId space, get iterator of Bindings.
-
- Iterator<BindingNodeId> chain = null ;
- // which comes out in sorted var order.
-
- Var v = action.getVar() ;
- for ( int i = 2 ; i < triples.size() ; )
- {
- // Next triples.
- Triple triple = triples.get(i) ;
- // Is it joined by a common variable?
- MergeActionVarIdx action2 = MergeLib.calcMergeAction(v, triple, indexes) ;
- if ( action2 == null )
- {}
- }
+
+ Iterator<BindingNodeId> iter1 = mergeJoin(triple1, triple2, nodeTable, indexes) ;
+ Iterator<Binding> iter2 = SolverLib.convertToNodes(iter1, nodeTable) ;
return null ;
}
- private static Iterator<BindingNodeId> exec(MergeActionIdxIdx action, Triple triple1, Triple triple2)
+ static Iterator<BindingNodeId> mergeJoin(Triple triple1, Triple triple2, NodeTable nodeTable, TupleIndex[] indexes)
{
- // Corresponds to triple1.
- IndexAccess access1 = action.getIndexAccess1() ;
- TupleIndex index1 = access1.getIndex() ;
- int len1 = access1.getPrefixLen() ;
- // Calc
-
-
- // from len1 prefix, to same+1
+ Tuple<NodeId> tuple1 = convert(nodeTable, triple1) ;
+ Tuple<NodeId> tuple2 = convert(nodeTable, triple2) ;
+ Tuple<Var> vars1 = vars(triple1) ;
+ Tuple<Var> vars2 = vars(triple2) ;
- IndexAccess access2 = action.getIndexAccess2() ;
- TupleIndex index2 = access2.getIndex() ;
- int len2 = access1.getPrefixLen() ;
+ MergeActionIdxIdx action = MergeLib.calcMergeAction(triple1, triple2, indexes) ;
+ Iterator<BindingNodeId> iter1 = merge(action, tuple1, vars1, tuple2, vars2) ;
+ return iter1 ;
+ }
+
+ private static Iterator<BindingNodeId> merge(MergeActionIdxIdx action,
+ Tuple<NodeId> tuple1, Tuple<Var> vars1,
+ Tuple<NodeId> tuple2, Tuple<Var> vars2)
+ {
+ int len1 = action.getIndexAccess1().getPrefixLen() ;
+ int len2 = action.getIndexAccess2().getPrefixLen() ;
+ TupleIndex tupleIndex1 = action.getIndexAccess1().getIndex() ;
+ TupleIndex tupleIndex2 = action.getIndexAccess2().getIndex() ;
- Var var1 = access1.getVar() ;
- Var var2 = access2.getVar() ;
- // var1 == var2
- Var var = var1 ;
+ Iterator<Tuple<NodeId>> iter1 = tupleIndex1.find(tuple1) ;
+ if ( false )
+ {
+ System.out.println("-- Left:") ;
+ Iter.print(iter1) ;
+ iter1 = tupleIndex1.find(tuple1) ;
+ }
-
+ Iterator<Tuple<NodeId>> iter2 = tupleIndex2.find(tuple2) ;
+ if ( false )
+ {
+ System.out.println("-- Right:") ;
+ Iter.print(iter2) ;
+ iter2 = tupleIndex2.find(tuple2) ;
+ System.out.println("----") ;
+ }
+ Tuple<NodeId> row1 = null ;
+ Tuple<NodeId> row2 = null ;
+ List<BindingNodeId> results = new ArrayList<>() ;
+ List<Tuple<NodeId>> tmp1 = new ArrayList<>() ;
+ List<Tuple<NodeId>> tmp2 = new ArrayList<>() ;
- return null ;
+ for(;;)
+ {
+ if ( row1 == null )
+ {
+ if ( ! iter1.hasNext() )
+ break ;
+ row1 = iter1.next() ;
+ }
+ if ( row2 == null )
+ {
+ if ( ! iter2.hasNext() )
+ break ;
+ row2 = iter2.next() ;
+ }
+
+ NodeId join1 = tupleIndex1.getColumnMap().fetchSlot(len1, row1) ;
+ NodeId join2 = tupleIndex2.getColumnMap().fetchSlot(len2, row2) ;
+
+ long v1 = join1.getId() ;
+ long v2 = join2.getId() ;
+
+ if ( v1 == v2 )
+ {
+ long v = v1 ;
+ row1 = advance(v, tupleIndex1, len1, iter1, tmp1, row1) ;
+ row2 = advance(v, tupleIndex2, len2, iter2, tmp2, row2) ;
+ join(results, action.getVar(), vars1, tmp1, vars2, tmp2) ;
+ }
+ else if ( v1 > v2 )
+ {
+ row2 = null ;
+ }
+ else
+ {
+ // v1 < v2
+ row1 = null ;
+ }
+ }
+ return results.iterator() ;
}
-
- private static Iterator<BindingNodeId> exec(MergeActionVarIdx action, Iterator<BindingNodeId> iterator, Triple triple)
+
+ private static Tuple<NodeId> advance(long v, TupleIndex tupleIndex , int len , Iterator<Tuple<NodeId>> iter, List<Tuple<NodeId>> acc, Tuple<NodeId> row)
{
- // Corresponds to triple1.
- IndexAccess access = action.getIndexAccess() ;
- TupleIndex index = access.getIndex() ;
- int len = access.getPrefixLen() ;
- Var var = access.getVar() ;
-
- return null ;
+ for (;;)
+ {
+ // Overshoot :-(
+ long v1 = tupleIndex.getColumnMap().fetchSlot(len, row).getId() ;
+ if ( v != v1 )
+ break ;
+ acc.add(row) ;
+ if ( ! iter.hasNext() )
+ return null ;
+ row = iter.next() ;
+ }
+ return row ;
}
-
-
- private static Iterator<Tuple<NodeId>> exec(TupleIndex index, int len, Triple triple, NodeTable nodeTable)
+
+ private static void join(List<BindingNodeId> results, Var joinVar,
+ Tuple<Var> vars1 , List<Tuple<NodeId>> tmp1,
+ Tuple<Var> vars2 , List<Tuple<NodeId>> tmp2)
{
-
-
-
-
- return null ;
+ if ( false ) System.out.println("join left="+tmp1.size()+" right="+tmp2.size()) ;
+ for ( Tuple<NodeId> row1 : tmp1 )
+ for ( Tuple<NodeId> row2 : tmp2 )
+ {
+ if ( false ) System.out.println("Join: "+row1+" "+row2) ;
+ BindingNodeId b = new BindingNodeId((Binding)null) ;
+ b = bind(b, joinVar, row1, vars1) ;
+ if ( b == null )
+ continue ;
+ b = bind(b, joinVar, row2, vars2) ;
+ if ( b == null )
+ continue ;
+ if ( false ) System.out.println("Bind => "+b) ;
+ results.add(b) ;
+ }
+ tmp1.clear() ;
+ tmp2.clear() ;
}
+
+ static BindingNodeId bind(BindingNodeId b, Var joinVar, Tuple<NodeId> row, Tuple<Var> vars)
+ {
+ // Tuples from indexes are in natural order.
+ if ( false ) System.out.println("Bind: "+vars+" "+row) ;
+ for ( int i = 0 ; i < vars.size() ; i++ )
+ {
+ Var v = vars.get(i) ;
+ if ( v == null )
+ continue ;
+ NodeId id = row.get(i) ;
+ NodeId id2 = b.get(v) ;
+ if ( id2 != null && ( id2.getId() != id.getId() ) )
+ return null ;
+ b.put(v, id) ;
+ }
+ return b ;
+ }
+
static Tuple<NodeId> convert(NodeTable nodeTable, Triple triple)
{
return convert(nodeTable, triple.getSubject(), triple.getPredicate(), triple.getObject()) ;
View
43 src/main/java/projects/merge/TestMergeJoin.java
@@ -18,7 +18,6 @@
package projects.merge;
-import org.junit.BeforeClass ;
import org.junit.Test ;
import org.openjena.atlas.junit.BaseTest ;
@@ -33,36 +32,29 @@
{
static Location loc = Location.mem() ;
- static TupleIndex POS ;
- static TupleIndex PSO ;
- static TupleIndex [] indexes ;
-
- @BeforeClass public static void beforeClass()
- {
- POS = SetupTDB.makeTupleIndex(loc, "SPO", "POS", "POS", 3*NodeId.SIZE) ;
- PSO = SetupTDB.makeTupleIndex(loc, "SPO", "PSO", "PSO", 3*NodeId.SIZE) ;
- indexes = new TupleIndex[]{ POS, PSO } ;
- }
+ static TupleIndex SPO = SetupTDB.makeTupleIndex(loc, "SPO", "SPO", "SPO", 3*NodeId.SIZE) ;
+ static TupleIndex POS = SetupTDB.makeTupleIndex(loc, "SPO", "POS", "POS", 3*NodeId.SIZE) ;
+ static TupleIndex PSO = SetupTDB.makeTupleIndex(loc, "SPO", "PSO", "PSO", 3*NodeId.SIZE) ;
+ static TupleIndex OSP = SetupTDB.makeTupleIndex(loc, "SPO", "OSP", "OSP", 3*NodeId.SIZE) ;
- @Test public void chooseMerge_01() { test("(?s <p> ?o)", "(?s <q> 123)", indexes, PSO, POS) ; }
- @Test public void chooseMerge_02() { test("(?s <p> ?o)", "(?s <q> ?v)", indexes, PSO, PSO) ; }
- @Test public void chooseMerge_03() { test("(?s <p> ?z)", "(?z <q> ?v)", indexes, POS, PSO) ; }
- @Test public void chooseMerge_04() { test("(?s <p> ?z)", "(?z <q> 123)", indexes, POS, POS) ; }
- @Test public void chooseMerge_05() { test("(?x <p> ?x)", "(?x <q> ?v)", indexes, PSO, PSO) ; }
- @Test public void chooseMerge_06() { test("(?a <p> ?b)", "(?c <q> ?d)", indexes, null, null) ; }
+ static TupleIndex [] indexesP2 = { POS, PSO } ;
+ static TupleIndex [] indexes1 = { SPO, POS, OSP } ;
+
+ // tests with partial index coverage.
+
+ @Test public void chooseMerge_01() { test("(?s <p> ?o)", "(?s <q> 123)", indexesP2, PSO, POS) ; }
+ @Test public void chooseMerge_02() { test("(?s <p> ?o)", "(?s <q> ?v)", indexesP2, PSO, PSO) ; }
+ @Test public void chooseMerge_03() { test("(?s <p> ?z)", "(?z <q> ?v)", indexesP2, POS, PSO) ; }
+ @Test public void chooseMerge_04() { test("(?s <p> ?z)", "(?z <q> 123)", indexesP2, POS, POS) ; }
+ @Test public void chooseMerge_05() { test("(?x <p> ?x)", "(?x <q> ?v)", indexesP2, PSO, PSO) ; }
+ @Test public void chooseMerge_06() { test("(?a <p> ?b)", "(?c <q> ?d)", indexesP2, null, null) ; }
+
+ @Test public void chooseMerge_10() { test("(?s <p> ?o)", "(?s <q> 123)", indexes1, PSO, POS) ; }
private static void test(String tripleStr1, String tripleStr2, TupleIndex[] indexes, TupleIndex index1, TupleIndex index2)
{
Triple triple1 = SSE.parseTriple(tripleStr1) ;
Triple triple2 = SSE.parseTriple(tripleStr2) ;
-
-// System.out.print("Join: ") ;
-// SSE.write(triple1) ;
-// System.out.print(" ") ;
-// SSE.write(triple2) ;
-// System.out.println() ;
-
- //System.out.println("{"+triple1+"} {"+triple2+"}") ;
MergeActionIdxIdx action = MergeLib.calcMergeAction(triple1, triple2, indexes) ;
if ( index1 != null )
@@ -78,7 +70,6 @@ private static void test(String tripleStr1, String tripleStr2, TupleIndex[] inde
assertEquals(index1, i1) ;
assertEquals(index2, i2) ;
- //System.out.println("** Expected: "+index1+"-"+index2+" : Got "+i1+"-"+i2) ;
}
}

No commit comments for this range

Something went wrong with that request. Please try again.