diff --git a/src/main/java/projects/merge/JoinMerge.java b/src/main/java/projects/merge/JoinMerge.java index 4b011c8..5bdb4c5 100644 --- a/src/main/java/projects/merge/JoinMerge.java +++ b/src/main/java/projects/merge/JoinMerge.java @@ -78,33 +78,31 @@ private static void test(String tripleStr1, String tripleStr2, String[] indexes, System.out.println() ; //System.out.println("{"+triple1+"} {"+triple2+"}") ; - Pair p = choose(triple1, triple2, indexes) ; + MergeAction action = choose(triple1, triple2, indexes) ; - if ( p == null ) + if ( action == null ) { System.out.println("** No match") ; return ; } - String i1 = p.getLeft() ; - String i2 = p.getRight() ; + String i1 = action.index1 ; + String i2 = action.index2 ; if ( !index1.equals(i1) || !index2.equals(i2) ) System.out.println("** Expected: "+index1+"-"+index2+" : Got "+i1+"-"+i2) ; else - System.out.println("** "+i1+"-"+i2) ; + System.out.println("** "+action) ; System.out.println() ; } - private static Pair choose(Triple triple1, Triple triple2, String[] indexes) + private static MergeAction choose(Triple triple1, Triple triple2, String[] indexes) { - // Join vars. - Tuple const1 = constants(triple1) ; Tuple const2 = constants(triple2) ; - int x1 = const1.countNotNull() ; - int x2 = const2.countNotNull() ; +// int x1 = const1.countNotNull() ; +// int x2 = const2.countNotNull() ; // print(const1, indexes) ; // print(const2, indexes) ; @@ -113,79 +111,87 @@ private static Pair choose(Triple triple1, Triple triple2, Strin // Look for join vars. Set vars1 = VarUtils.getVars(triple1) ; Set vars2 = VarUtils.getVars(triple2) ; - Set joinVars = SetUtils.intersection(vars1, vars2) ; - //System.out.println("Join: "+joinVars) ; - // Find join linkages. // Assume one for now. Pair linkage = joinLinkages(triple1, triple2) ; - // There parts. - // Const, vars, remainederr + // Const, vars, remainder if ( linkage == null ) { System.out.println("No linkage") ; + return null ; } - else - { - // Base index for - String prefix1 = constantIndexPrefix(triple1) ; - String prefix2 = constantIndexPrefix(triple2) ; - System.out.print("Prefixes="+prefix1+"/"+prefix2) ; - System.out.println(" JoinVars="+joinVars+" Linkage="+linkage) ; + + Set _joinVars = SetUtils.intersection(vars1, vars2) ; + Var joinVar = _joinVars.iterator().next(); + //System.out.println("Join: "+joinVars) ; - // .. conclusion. - String idxPrefix1 = prefix1+linkage.getLeft(); - String idxPrefix2 = prefix2+linkage.getRight(); - //System.out.println("Calc: "+idx1+"-"+idx2) ; - - // 0 - contants - // 1 - join var cols - // 2 - rest - 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 ; - + // Base index for + String prefix1 = constantIndexPrefix(triple1) ; + String prefix2 = constantIndexPrefix(triple2) ; +// System.out.print("Prefixes="+prefix1+"/"+prefix2) ; +// System.out.println(" JoinVar="+joinVar+" Linkage="+linkage) ; + + // .. conclusion. + String idxPrefix1 = prefix1+linkage.getLeft(); + String idxPrefix2 = prefix2+linkage.getRight(); + //System.out.println("Calc: "+idx1+"-"+idx2) ; - for ( String index : indexes ) + // 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 ; + + for ( String index : indexes ) + { + if ( index.startsWith(idxPrefix1)) { - if ( index.startsWith(idxPrefix1)) - { - if ( joinIndex1[2] != null ) - System.out.println("Choices! (1) : "+index) ; - else - joinIndex1[2] = index.substring(idxPrefix1.length()) ; - } - if ( index.startsWith(idxPrefix2)) - { - if ( joinIndex2[2] != null ) - System.out.println("Choices! (2) : "+index) ; - else - joinIndex2[2] = index.substring(idxPrefix2.length()) ; - } + if ( joinIndex1[2] != null ) + System.out.println("Choices! (1) : "+index) ; + else + joinIndex1[2] = index.substring(idxPrefix1.length()) ; + } + if ( index.startsWith(idxPrefix2)) + { + if ( joinIndex2[2] != null ) + System.out.println("Choices! (2) : "+index) ; + else + joinIndex2[2] = index.substring(idxPrefix2.length()) ; } - - - String s1 = strJoinIndex(joinIndex1) ; - String s2 = strJoinIndex(joinIndex2) ; - System.out.println("Decision: "+s1+" "+s2) ; } - // Another way of thinking about it. - // Generate possibilities. + + String s1 = strJoinIndex(joinIndex1) ; + String s2 = strJoinIndex(joinIndex2) ; + //System.out.println("Decision: "+s1+" "+s2) ; + return new MergeAction(s1, s2, + prefix1, prefix2, + joinVar + ) ; + + } + + // Another way of thinking about it. + // Generate possibilities. + private static Pair calcMergeJoin2(Triple triple1, Triple triple2, String[] indexes) + { if ( constants(triple1.getPredicate()) == null || - constants(triple2.getPredicate()) == null ) - { - System.out.println("Not a P-P pair") ; - return null ; - } + constants(triple2.getPredicate()) == null ) + { + System.out.println("Not a P-P pair") ; + return null ; + } + String i1 ; String i2 ; @@ -219,7 +225,8 @@ else if ( varMatch(triple1.getObject(), triple2.getObject()) ) private static String strJoinIndex(String[] joinIndex) { - return "["+joinIndex[0]+","+joinIndex[1]+","+joinIndex[2]+"]" ; + return joinIndex[0]+joinIndex[1]+joinIndex[2] ; + //return "["+joinIndex[0]+","+joinIndex[1]+","+joinIndex[2]+"]" ; } private static String constantIndexPrefix(Triple triple) diff --git a/src/main/java/projects/merge/MergeAction.java b/src/main/java/projects/merge/MergeAction.java new file mode 100644 index 0000000..fc57bb3 --- /dev/null +++ b/src/main/java/projects/merge/MergeAction.java @@ -0,0 +1,48 @@ +/* + * 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 ; + +public class MergeAction +{ + public String index1 ; + public String index2 ; + public String prefix1 ; + public String prefix2 ; + public Var joinVar ; // This is the first col after the prefix + + public MergeAction(String index1, String index2, + String prefix1, String prefix2, + Var joinVar) + { + super() ; + this.index1 = index1 ; + this.index2 = index2 ; + this.prefix1 = prefix1 ; + this.prefix2 = prefix2 ; + this.joinVar = joinVar ; + } + + @Override + public String toString() + { + return "[Join("+index1+","+index2+") ("+prefix1+","+prefix2+") "+joinVar+"]" ; + } +} diff --git a/src/main/java/projects/merge/TupleIndexPrefix.java b/src/main/java/projects/merge/TupleIndexPrefix.java new file mode 100644 index 0000000..dc88c00 --- /dev/null +++ b/src/main/java/projects/merge/TupleIndexPrefix.java @@ -0,0 +1,32 @@ +/* + * 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 java.util.Iterator ; + +import org.openjena.atlas.lib.Tuple ; + +import com.hp.hpl.jena.tdb.index.TupleIndex ; +import com.hp.hpl.jena.tdb.store.NodeId ; + +public interface TupleIndexPrefix extends TupleIndex +{ + /** Find all the entries which start with thegiven prefix */ + public Iterator> findPrefix(Tuple pattern) ; +} diff --git a/src/main/java/projects/merge/TupleIndexPrefixSimple.java b/src/main/java/projects/merge/TupleIndexPrefixSimple.java new file mode 100644 index 0000000..3ba18f6 --- /dev/null +++ b/src/main/java/projects/merge/TupleIndexPrefixSimple.java @@ -0,0 +1,51 @@ +/* + * 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 java.util.Arrays ; +import java.util.Iterator ; + +import org.openjena.atlas.lib.Tuple ; + +import com.hp.hpl.jena.tdb.index.TupleIndex ; +import com.hp.hpl.jena.tdb.store.NodeId ; + +public class TupleIndexPrefixSimple extends TupleIndexWrapper implements TupleIndexPrefix +{ + + public TupleIndexPrefixSimple(TupleIndex index) + { + super(index) ; + } + + @Override + public Iterator> findPrefix(Tuple pattern) + { + // Does not exploit the features of the index. + // Extend the Tuple to table width. + int patternLen = getTupleLength() ; + int indexLen = getTupleLength() ; + NodeId[] x = new NodeId[indexLen] ; + System.arraycopy(pattern.tuple(), 0, x, 0, patternLen) ; + Arrays.fill(x, patternLen, indexLen, NodeId.NodeIdAny) ; + return find(Tuple.create(x)) ; + } + +} + diff --git a/src/main/java/projects/merge/TupleIndexWrapper.java b/src/main/java/projects/merge/TupleIndexWrapper.java new file mode 100644 index 0000000..e1ff9d9 --- /dev/null +++ b/src/main/java/projects/merge/TupleIndexWrapper.java @@ -0,0 +1,100 @@ +/* + * 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 java.util.Iterator ; + +import org.openjena.atlas.lib.Tuple ; + +import com.hp.hpl.jena.tdb.index.TupleIndex ; +import com.hp.hpl.jena.tdb.store.NodeId ; + +public class TupleIndexWrapper implements TupleIndex +{ + protected final TupleIndex index ; + + public TupleIndexWrapper(TupleIndex index) { this.index = index ; } + + @Override + public boolean add(Tuple tuple) + { + return index.add(tuple) ; + } + + @Override + public boolean delete(Tuple tuple) + { + return index.delete(tuple) ; + } + + @Override + public Iterator> find(Tuple pattern) + { + return index.find(pattern) ; + } + + @Override + public Iterator> all() + { + return index.all() ; + } + + @Override + public int getTupleLength() + { + return index.getTupleLength() ; + } + + @Override + public String getLabel() + { + return index.getLabel() ; + } + + @Override + public int weight(Tuple pattern) + { + return index.weight(pattern) ; + } + + @Override + public long size() + { + return index.size() ; + } + + @Override + public boolean isEmpty() + { + return index.isEmpty() ; + } + + @Override + public void clear() + { index.clear() ; } + + @Override + public void sync() + { index.sync() ; } + + @Override + public void close() + { index.close() ; } +} +