Skip to content
Browse files

Re-work.

  • Loading branch information...
1 parent af3c407 commit cacbfae71c263a3f85c5e6844a030e27ef4cf97b Andy Seaborne committed
View
6 pom.xml
@@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>
- <groupId>com.hp.hpl.jena</groupId>
+ <groupId>org.apache.jena</groupId>
<artifactId>afs</artifactId>
<packaging>jar</packaging>
<name>AFS</name>
@@ -128,6 +128,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
<configuration>
<encoding>UTF-8</encoding>
<debug>true</debug>
@@ -141,6 +142,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
+ <version>2.12</version>
<configuration>
<includes>
<include>**/TS_*.java</include>
@@ -151,6 +153,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
+ <version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
@@ -168,6 +171,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
+ <version>2.9</version>
<configuration>
<buildOutputDirectory>${project.build.directory}/classes-eclipse</buildOutputDirectory>
<downloadSources>true</downloadSources>
View
59 src/main/java/projects/merge/IndexAccess.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package projects.merge;
+
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.tdb.index.TupleIndex ;
+
+public class IndexAccess
+{
+ // Special cases:
+ // Two vars: ?x <p> ?x
+ // Three vars: ?x ?x ?x
+ private TupleIndex index ;
+ private int prefixLen ;
+ private Var var ;
+
+ public IndexAccess(TupleIndex index, int prefixLen, Var var)
+ {
+ this.index = index ;
+ this.prefixLen = prefixLen ;
+ this.var = var ;
+ }
+
+ public int getPrefixLen() { return prefixLen ; }
+
+ public TupleIndex getIndex() { return index ; }
+
+ public Var getVar() { return var ; }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder() ;
+ builder.append("[")
+ .append(index.getName())
+ .append("/")
+ .append(index.getName().substring(0, prefixLen))
+ .append("->")
+ .append(var)
+ .append("]") ;
+ return builder.toString() ;
+ }
+}
View
183 src/main/java/projects/merge/Main.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package projects.merge;
+
+import static projects.merge.Main.ColNames.O ;
+import static projects.merge.Main.ColNames.P ;
+import static projects.merge.Main.ColNames.S ;
+import org.openjena.atlas.lib.ColumnMap ;
+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.Triple ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.sse.SSE ;
+import com.hp.hpl.jena.tdb.base.file.Location ;
+import com.hp.hpl.jena.tdb.index.TupleIndex ;
+import com.hp.hpl.jena.tdb.store.NodeId ;
+import com.hp.hpl.jena.tdb.sys.SetupTDB ;
+
+public class Main
+{
+ // Preferred.
+ enum ColNames { S("S"), P("P"), O("O"), G("G") ;
+ private String col ;
+ ColNames(String col) { this.col = col ; }
+ @Override public String toString() { return col ;}
+ }
+
+ public static void main(String[] args)
+ {
+ // Setup
+ Log.setLog4j() ;
+ ColumnMap colMap = new ColumnMap("SPO", "POS") ;
+ 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 = { POS, PSO } ;
+ // Add "columns" to indexes.
+ Tuple<ColNames> primary = Tuple.create(S,P,O) ;
+ System.out.println(POS.getColumnMap().map(primary)) ;
+
+
+ // Setup
+ test("(?s <p> ?o)", "(?s <q> 123)", indexes, PSO, POS) ;
+ test("(?s <p> ?o)", "(?s <q> ?v)", indexes, PSO, PSO) ;
+ test("(?s <p> ?z)", "(?z <q> ?v)", indexes, POS, PSO) ;
+
+ test("(?s <p> ?z)", "(?z <q> 123)", indexes, POS, POS) ;
+ test("(?x <p> ?x)", "(?x <q> ?v)", indexes, PSO, PSO) ;
+
+ test("(?a <p> ?b)", "(?c <q> ?d)", indexes, PSO, PSO) ;
+
+ }
+
+ 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+"}") ;
+ MergeAction action = choose(triple1, triple2, indexes) ;
+
+ if ( action == null )
+ {
+ System.out.println("** No match") ;
+ return ;
+ }
+ TupleIndex i1 = action.getIndexAccess1().getIndex() ;
+ TupleIndex i2 = action.getIndexAccess2().getIndex() ;
+
+ if ( !index1.equals(i1) || !index2.equals(i2) )
+ System.out.println("** Expected: "+index1+"-"+index2+" : Got "+i1+"-"+i2) ;
+ else
+ System.out.println("** "+action) ;
+ System.out.println() ;
+ }
+
+ private static MergeAction choose(Triple triple1, Triple triple2, TupleIndex[] indexes)
+ {
+ IndexAccess[] access1 = access(triple1, indexes) ;
+ IndexAccess[] access2 = access(triple2, indexes) ;
+
+// System.out.println(Arrays.asList(access1)) ;
+// System.out.println(Arrays.asList(access2)) ;
+
+ MergeAction action = null ;
+ for ( IndexAccess a1 : access1 )
+ {
+ if ( a1 == null ) continue ;
+ for ( IndexAccess a2 : access2 )
+ {
+ if ( a2 == null ) continue ;
+ if ( a1.getVar().equals(a2.getVar()))
+ {
+ MergeAction action2 = new MergeAction(a1,a2) ;
+ // Longest prefixes.
+ if ( action == null )
+ action = action2 ;
+ else
+ {
+ System.out.println("Choose: "+action+" // "+action2) ;
+ // Choose one with most prefixing.
+ int len1 = action.getIndexAccess1().getPrefixLen()+action.getIndexAccess2().getPrefixLen() ;
+ int len2 = action2.getIndexAccess1().getPrefixLen()+action2.getIndexAccess2().getPrefixLen() ;
+ if ( len2 == len1 )
+ {
+ // Example: same var uses more than once in a triple.
+ if ( action2.getIndexAccess1().getIndex() == action2.getIndexAccess2().getIndex() )
+ // Prefer same index.
+ // Better - special action.
+ action = action2 ;
+ }
+ else if ( len2 > len1 )
+ action = action2 ;
+ // else do nothing.
+ }
+
+
+
+ }
+ }
+ }
+ return action ;
+ }
+
+ private static IndexAccess[] access(Triple _triple, TupleIndex[] indexes)
+ {
+ IndexAccess[] accesses = new IndexAccess[indexes.length] ;
+ Tuple<Node> triple = tripleAsTuple(_triple) ;
+ int i = 0 ;
+ for ( TupleIndex idx : indexes )
+ {
+ IndexAccess a = access(triple, idx) ;
+ accesses[i++] = a ;
+ }
+
+ return accesses ;
+ }
+
+ private static IndexAccess access(Tuple<Node> triple, TupleIndex idx)
+ {
+ Tuple<Node> t = idx.getColumnMap().map(triple) ;
+ for ( int i = 0 ; i < triple.size() ; i++ )
+ {
+ Node n = t.get(i) ;
+ if ( Var.isVar(n) )
+ return new IndexAccess(idx, i, Var.alloc(n)) ;
+ }
+ return null ;
+ }
+
+ private static Tuple<Node> tripleAsTuple(Triple triple)
+ {
+ return Tuple.create(triple.getSubject(),
+ triple.getPredicate(),
+ triple.getObject()) ;
+ }
+}
View
47 src/main/java/projects/merge/MergeAction.java
@@ -18,32 +18,41 @@
package projects.merge;
-import com.hp.hpl.jena.sparql.core.Var ;
-import com.hp.hpl.jena.tdb.index.TupleIndex ;
-
public class MergeAction
{
- public TupleIndex index1 ;
- public TupleIndex index2 ;
- public String prefix1 ;
- public String prefix2 ;
- public Var joinVar ; // This is the first col after the prefix
+ private IndexAccess indexAccess1 ;
+ private IndexAccess indexAccess2 ;
- public MergeAction(TupleIndex index1, TupleIndex index2,
- String prefix1, String prefix2,
- Var joinVar)
+ public MergeAction(IndexAccess indexAccess1, IndexAccess indexAccess2)
{
super() ;
- this.index1 = index1 ;
- this.index2 = index2 ;
- this.prefix1 = prefix1 ;
- this.prefix2 = prefix2 ;
- this.joinVar = joinVar ;
+ this.indexAccess1 = indexAccess1 ;
+ this.indexAccess2 = indexAccess2 ;
+ if ( ! indexAccess1.getVar().equals(indexAccess2.getVar()) )
+ // May relax this and allow (?x = ?y AS ?z)
+ throw new InternalError("IndexAcceses in a merge must be joining the same variable") ;
}
-
+
+ public IndexAccess getIndexAccess1()
+ {
+ return indexAccess1 ;
+ }
+
+ public IndexAccess getIndexAccess2()
+ {
+ return indexAccess2 ;
+ }
+
@Override
- public String toString()
+ public String toString()
{
- return "[Join("+index1.getName()+","+index2.getName()+") ("+prefix1+","+prefix2+") "+joinVar+"]" ;
+ StringBuilder builder = new StringBuilder() ;
+ builder.append("MergeAction [") ;
+ builder.append(indexAccess1) ;
+ builder.append(",") ;
+ builder.append(indexAccess2) ;
+ builder.append("]") ;
+ return builder.toString() ;
}
+
}
View
4 src/main/java/projects/merge/Archive.java → src/main/java/projects/merge1/Archive1.java
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package projects.merge;
+package projects.merge1;
import java.util.ArrayList ;
import java.util.Arrays ;
@@ -31,7 +31,7 @@
import com.hp.hpl.jena.graph.Triple ;
import com.hp.hpl.jena.sparql.core.Var ;
-public class Archive
+public class Archive1
{
// Another way of thinking about it.
private static Pair<String,String> calcMergeJoin2(Triple triple1, Triple triple2, String[] indexes)
View
131 src/main/java/projects/merge/JoinMerge.java → src/main/java/projects/merge1/Archive2.java
@@ -16,14 +16,11 @@
* limitations under the License.
*/
-package projects.merge;
+package projects.merge1;
import java.util.Set ;
-import org.openjena.atlas.lib.ColumnMap ;
-import org.openjena.atlas.lib.Pair ;
-import org.openjena.atlas.lib.SetUtils ;
-import org.openjena.atlas.lib.Tuple ;
+import org.openjena.atlas.lib.* ;
import org.openjena.atlas.logging.Log ;
import com.hp.hpl.jena.graph.Node ;
@@ -36,7 +33,7 @@
import com.hp.hpl.jena.tdb.store.NodeId ;
import com.hp.hpl.jena.tdb.sys.SetupTDB ;
-public class JoinMerge
+public class Archive2
{
public static void main(String ... argv)
{
@@ -71,7 +68,7 @@ private static void test(String tripleStr1, String tripleStr2, TupleIndex[] inde
System.out.println() ;
//System.out.println("{"+triple1+"} {"+triple2+"}") ;
- MergeAction action = choose(triple1, triple2, indexes) ;
+ MergeAction1 action = choose(triple1, triple2, indexes) ;
if ( action == null )
{
@@ -87,9 +84,54 @@ private static void test(String tripleStr1, String tripleStr2, TupleIndex[] inde
System.out.println("** "+action) ;
System.out.println() ;
}
-
- private static MergeAction choose(Triple triple1, Triple triple2, TupleIndex[] indexes)
+ // Preferred.
+ enum ColNames { S("S"), P("P"), O("O"), G("G") ;
+ private String col ;
+ ColNames(String col) { this.col = col ; }
+ @Override public String toString() { return col ;}
+ }
+
+ static class ColumnName
+ {
+ @Override
+ public String toString()
+ {
+ return string ;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31 ;
+ int result = 1 ;
+ result = prime * result + ((string == null) ? 0 : string.hashCode()) ;
+ return result ;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj) return true ;
+ if (obj == null) return false ;
+ if (getClass() != obj.getClass()) return false ;
+ ColumnName other = (ColumnName)obj ;
+ return Lib.equal(this.string, other.string) ;
+ }
+
+ private final String string ;
+
+ public ColumnName(String string)
+ { this.string = string ; }
+
+ public static ColumnName create(String colName) { return new ColumnName(colName.intern()) ; }
+ }
+
+ static ColumnName _S = ColumnName.create("S") ;
+ static ColumnName _P = ColumnName.create("P") ;
+ static ColumnName _O = ColumnName.create("O") ;
+
+ private static MergeAction1 choose(Triple triple1, Triple triple2, TupleIndex[] indexes)
{
Tuple<String> const1 = constants(triple1) ;
Tuple<String> const2 = constants(triple2) ;
@@ -102,10 +144,9 @@ private static MergeAction choose(Triple triple1, Triple triple2, TupleIndex[] i
// Assume P fixed.
// Look for join vars.
- Set<Var> vars1 = VarUtils.getVars(triple1) ;
- Set<Var> vars2 = VarUtils.getVars(triple2) ;
// Find join linkages.
// Assume one for now.
+
Pair<String, String> linkage = joinLinkages(triple1, triple2) ;
// Const, vars, remainder
@@ -116,6 +157,8 @@ private static MergeAction choose(Triple triple1, Triple triple2, TupleIndex[] i
return null ;
}
+ Set<Var> vars1 = VarUtils.getVars(triple1) ;
+ Set<Var> vars2 = VarUtils.getVars(triple2) ;
Set<Var> _joinVars = SetUtils.intersection(vars1, vars2) ;
Var joinVar = _joinVars.iterator().next();
//System.out.println("Join: "+joinVars) ;
@@ -131,19 +174,6 @@ private static MergeAction choose(Triple triple1, Triple triple2, TupleIndex[] i
String idxPrefix2 = prefix2+linkage.getRight();
//System.out.println("Calc: "+idx1+"-"+idx2) ;
- // 0 - contants
- // 1 - join var cols
- // 2 - rest
- // Make a class? JoinIndexAccess
- String[] joinIndex1 = new String[3] ;
- joinIndex1[0] = prefix1 ;
- joinIndex1[1] = linkage.getLeft();
- joinIndex1[2] = null ;
- String[] joinIndex2 = new String[3] ;
- joinIndex2[0] = prefix2 ;
- joinIndex2[1] = linkage.getRight();
- joinIndex2[2] = null ;
-
TupleIndex idx1 = null ;
TupleIndex idx2 = null ;
@@ -153,24 +183,17 @@ private static MergeAction choose(Triple triple1, Triple triple2, TupleIndex[] i
if ( idxStr.startsWith(idxPrefix1))
{
- if ( joinIndex1[2] != null )
+ if ( idx1 != null )
System.out.println("Choices! (1) : "+idxStr) ;
else
- {
idx1 = index ;
- joinIndex1[2] = idxStr.substring(idxPrefix1.length()) ;
-
- }
}
if ( idxStr.startsWith(idxPrefix2))
{
- if ( joinIndex2[2] != null )
+ if ( idx2 != null )
System.out.println("Choices! (2) : "+idxStr) ;
else
- {
idx2 = index ;
- joinIndex2[2] = idxStr.substring(idxPrefix2.length()) ;
- }
}
}
@@ -179,13 +202,17 @@ private static MergeAction choose(Triple triple1, Triple triple2, TupleIndex[] i
// String s2 = strJoinIndex(joinIndex2) ;
//System.out.println("Decision: "+s1+" "+s2) ;
- return new MergeAction(idx1, idx2,
+ return new MergeAction1(idx1, idx2,
prefix1, prefix2,
+ linkage.getLeft(), linkage.getRight(),
+ // Join cols.
joinVar
) ;
}
+ // ----
+ /** Return a pair of columns for a match of variables betwen two triples. */
private static Pair<String, String> joinLinkages(Triple triple1, Triple triple2)
{
String x = joinLinkage(triple1.getSubject(), triple2) ;
@@ -206,6 +233,7 @@ private static String joinLinkage(Node x, Triple triple)
if ( triple.getObject().equals(x) ) return "O" ;
return null ;
}
+ // ----
private static String constantIndexPrefix(Triple triple)
{
@@ -240,3 +268,38 @@ private static Node constants(Node node)
// }
}
+class MergeAction1
+{
+ public TupleIndex index1 ;
+ public TupleIndex index2 ;
+ public String prefix1 ;
+ public String prefix2 ;
+ public String joinCol1 ;
+ public String joinCol2 ;
+ public Var joinVar ; // This is the first col after the prefix
+
+ public MergeAction1(TupleIndex index1, TupleIndex index2,
+ String prefix1, String prefix2, // cols
+ String joinCol1 , String joinCol2,
+ Var joinVar)
+ {
+ super() ;
+ this.index1 = index1 ;
+ this.index2 = index2 ;
+ this.prefix1 = prefix1 ;
+ this.prefix2 = prefix2 ;
+ this.joinCol1 = joinCol1 ;
+ this.joinCol2 = joinCol2 ;
+ this.joinVar = joinVar ;
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("[Join(%s,%s) (%s[%s],%s[%s]) %s]",
+ index1.getName(), index2.getName(),
+ prefix1, joinCol1,
+ prefix2, joinCol2,
+ joinVar) ;
+ }
+}

0 comments on commit cacbfae

Please sign in to comment.
Something went wrong with that request. Please try again.