Strabon
changeset 1169:d41bcd569028 temporals
generalized spatialJoinOptimizer into an abstract class to be extended by the spatial and temporal optimizers respectively. There is a bug when the spatial and temporal optimizer operate on the same time, I have to fix this
author | Konstantina Bereta <Konstantina.Bereta@di.uoa.gr> |
---|---|
date | Fri May 10 19:27:31 2013 +0300 (2013-05-10) |
parents | c003d2c1a053 |
children | 2aaa9fc419cf |
files | evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/SpatialJoinOptimizer.java evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/TemporalJoinOptimizer.java generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBQueryOptimizer.java |
line diff
1.1 --- a/evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/SpatialJoinOptimizer.java Fri May 10 16:10:00 2013 +0300 1.2 +++ b/evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/SpatialJoinOptimizer.java Fri May 10 19:27:31 2013 +0300 1.3 @@ -46,8 +46,10 @@ 1.4 * A query optimizer that re-orders nested Joins. 1.5 * 1.6 * @author Manos Karpathiotakis <mk@di.uoa.gr> 1.7 + * 1.8 + * @author Konstantina Bereta <Konstantina.Bereta@di.uoa.gr> 1.9 */ 1.10 -public class SpatialJoinOptimizer 1.11 +public class SpatialJoinOptimizer extends SpatioTemporalJoinOptimizer 1.12 //implements QueryOptimizer //Removed it consciously 1.13 { 1.14 1.15 @@ -63,682 +65,36 @@ 1.16 tupleExpr.visit(new JoinVisitor(spatialJoins)); 1.17 } 1.18 1.19 - protected class JoinVisitor extends QueryModelVisitorBase<RuntimeException> { 1.20 - 1.21 - 1.22 - 1.23 - public JoinVisitor(List<TupleExpr> spatialJoins) { 1.24 - super(); 1.25 - this.spatialJoins = spatialJoins; 1.26 + 1.27 + protected boolean isRelevantSTFunc(FunctionCall functionCall) 1.28 + { 1.29 + Function function = FunctionRegistry.getInstance().get(functionCall.getURI()); 1.30 + if(function instanceof SpatialConstructFunc) 1.31 + { 1.32 + //TODO may have to comment this part again 1.33 + //uncommented because I use this function in the case of metrics 1.34 + return true; 1.35 } 1.36 - 1.37 - 1.38 - private List<TupleExpr> spatialJoins; 1.39 - //buffer with a var as a second argument 1.40 - private boolean problematicBuffer = false; 1.41 - 1.42 - //indicates whether a metric expression contains a spatial function call 1.43 - private boolean containsSpatial = false; 1.44 - private boolean optimizableMetricOrProperty = true; 1.45 - 1.46 - private int thematicJoinsSize = 0; 1.47 - 1.48 - //List<SpatialFilterInfo> allSFilters = new ArrayList<SpatialFilterInfo>(); 1.49 - Map<TupleExpr, List<Var>> allSFilters = new HashMap<TupleExpr, List<Var>>(); 1.50 - 1.51 - @Override 1.52 - public void meet(Join node) { 1.53 - 1.54 - //XXX NOTE: NOT OPTIMIZING CONTENTS OF OPTIONAL CLAUSE!!! 1.55 - //Reason1: Errors occurred in the condition of the LeftJoin containing the optional subgraph 1.56 - 1.57 - //Not as successful as I hoped. Some OPTIONAL clauses may pass 1.58 - if(parentIsOptional(node)) 1.59 - { 1.60 - return; 1.61 - } 1.62 - // if(node.getParentNode() instanceof LeftJoin) 1.63 - // { 1.64 - // return; 1.65 - // } 1.66 - 1.67 - // Recursively get the join arguments 1.68 - List<TupleExpr> joinArgs = getJoinArgs(node, new ArrayList<TupleExpr>()); 1.69 - 1.70 - if(joinArgs == null) 1.71 - { 1.72 - //2nd mechanism to avoid OPTIONAL clauses from passing 1.73 - return; 1.74 - } 1.75 - 1.76 - 1.77 - Map<TupleExpr, List<Var>> varsMap = new /*Linked*/HashMap<TupleExpr, List<Var>>(); 1.78 - 1.79 - for (TupleExpr tupleExpr : joinArgs) { 1.80 - varsMap.put(tupleExpr, getStatementPatternVars(tupleExpr)); 1.81 - 1.82 - } 1.83 - 1.84 - //Now I have all the info I need. Just need to structure it efficiently 1.85 - int allNodes = varsMap.size() + allSFilters.size(); 1.86 - thematicJoinsSize = varsMap.size(); 1.87 - //careful with positions on the diagonal! Do not utilize them! 1.88 - int joinsGraph[][] = new int[allNodes][allNodes]; 1.89 - 1.90 - //prints for debug 1.91 - // Set<TupleExpr> allExprs = varsMap.keySet(); 1.92 - // System.out.println(allExprs.toString()); 1.93 - // 1.94 - // Set<TupleExpr> allFilters = allSFilters.keySet(); 1.95 - // System.out.println(allFilters.toString()); 1.96 - 1.97 - //Thematic part first 1.98 - int i = 0; 1.99 - 1.100 - for(List<Var> listHorizontal : varsMap.values()) 1.101 - { 1.102 - int j = 0; 1.103 - int k = 0; 1.104 - 1.105 - //Other thematics 1.106 - for(List<Var> listVertical : varsMap.values()) 1.107 - { 1.108 - if(i==j) 1.109 - { 1.110 - j++; 1.111 - continue; 1.112 - } 1.113 - 1.114 - 1.115 - joinsGraph[i][j] = sameVar(listHorizontal, listVertical); 1.116 - 1.117 - j++; 1.118 - } 1.119 - 1.120 - //Spatials 1.121 - for(List<Var> listVertical : allSFilters.values()) 1.122 - { 1.123 - 1.124 - joinsGraph[i][k+varsMap.size()] = sameVar(listHorizontal, listVertical); 1.125 - 1.126 - k++; 1.127 - } 1.128 - 1.129 - i++; 1.130 - } 1.131 - 1.132 - //Now for the spatial horizontal nodes 1.133 - i = varsMap.size(); 1.134 - for(List<Var> listHorizontal : allSFilters.values()) 1.135 - { 1.136 - int j = 0; 1.137 - int k = 0; 1.138 - 1.139 - //Other thematics 1.140 - for(List<Var> listVertical : varsMap.values()) 1.141 - { 1.142 - 1.143 - joinsGraph[i][j] = sameVar(listHorizontal, listVertical); 1.144 - 1.145 - j++; 1.146 - } 1.147 - 1.148 - //Spatials 1.149 - for(List<Var> listVertical : allSFilters.values()) 1.150 - { 1.151 - if(i==k+varsMap.size()) 1.152 - { 1.153 - k++; 1.154 - continue; 1.155 - } 1.156 - 1.157 - joinsGraph[i][k+varsMap.size()] =sameVar(listHorizontal, listVertical); 1.158 - 1.159 - k++; 1.160 - } 1.161 - 1.162 - i++; 1.163 - } 1.164 - 1.165 - //Checking graph to be sure 1.166 - /* 1.167 - for(int a = 0; a < allNodes; a++) 1.168 - { 1.169 - for(int b = 0; b < allNodes; b++) 1.170 - { 1.171 - System.out.print(joinsGraph[a][b]+" "); 1.172 - 1.173 - } 1.174 - System.out.println(""); 1.175 - } 1.176 - */ 1.177 - 1.178 - //Time to construct ordered sequence of joins + filters 1.179 - List<TupleExpr> orderedJoinArgs = new ArrayList<TupleExpr>(allNodes); 1.180 - //maybe I won't need all the positions -> some spatial joins may not be utilized 1.181 - List<Integer> tempList = new ArrayList<Integer>(allNodes); 1.182 - List<Integer> pathList = new ArrayList<Integer>(); 1.183 - List<Integer> finalList = new ArrayList<Integer>(); 1.184 - Set<Var> varsTillNow = new LinkedHashSet<Var>(); 1.185 - for(int row = 0 ; row < allNodes ; row++) 1.186 - { 1.187 - tempList.add(row); 1.188 - createOrderedJoins(joinsGraph, row, row, 1, varsTillNow, tempList, pathList, finalList); 1.189 - pathList.clear(); 1.190 - if(finalList.size() == allNodes) 1.191 - { 1.192 - break; 1.193 - } 1.194 - 1.195 - } 1.196 - 1.197 - /* 1.198 - System.out.println("*--REWRITTEN TREE--**"); 1.199 - System.out.println(finalList.toString()); 1.200 - */ 1.201 - 1.202 - int varsMapSize = varsMap.size(); 1.203 - for(Integer position : finalList) 1.204 - { 1.205 - if(position<varsMapSize)//thematic! 1.206 - { 1.207 - int count = 0; 1.208 - Iterator it = varsMap.entrySet().iterator(); 1.209 - 1.210 - while (it.hasNext()) 1.211 - { 1.212 - { 1.213 - Map.Entry entry = (Map.Entry)it.next(); 1.214 - if(count == position) 1.215 - { 1.216 - orderedJoinArgs.add((TupleExpr) entry.getKey()); 1.217 - 1.218 - it.remove(); 1.219 - varsMapSize--; 1.220 - 1.221 - for(int fix = 0 ; fix < finalList.size(); fix++) 1.222 - { 1.223 - if(finalList.get(fix) > position) 1.224 - { 1.225 - int reduced = finalList.get(fix) - 1; 1.226 - finalList.set(fix, reduced); 1.227 - 1.228 - } 1.229 - } 1.230 - break; 1.231 - } 1.232 - count++; 1.233 - } 1.234 - } 1.235 - } 1.236 - else//spatial! 1.237 - { 1.238 - int count = 0; 1.239 - Iterator it = allSFilters.entrySet().iterator(); 1.240 - while (it.hasNext()) 1.241 - { 1.242 - { 1.243 - Map.Entry entry = (Map.Entry)it.next(); 1.244 - if(count == position - varsMapSize) 1.245 - { 1.246 - //If I keep record of this entry, I can use the info later to avoid duplicate filters 1.247 - spatialJoins.add((TupleExpr) entry.getKey()); 1.248 - // 1.249 - orderedJoinArgs.add((TupleExpr) entry.getKey()); 1.250 - it.remove(); 1.251 - for(int fix = 0 ; fix < finalList.size(); fix++) 1.252 - { 1.253 - if(finalList.get(fix) > position) 1.254 - { 1.255 - int reduced = finalList.get(fix) - 1; 1.256 - finalList.set(fix, reduced); 1.257 - } 1.258 - } 1.259 - break; 1.260 - } 1.261 - count++; 1.262 - } 1.263 - } 1.264 - } 1.265 - 1.266 - } 1.267 - //Must take care of the remainders as well! 1.268 - Iterator it = varsMap.entrySet().iterator(); 1.269 - while (it.hasNext()) 1.270 - { 1.271 - Map.Entry entry = (Map.Entry)it.next(); 1.272 - orderedJoinArgs.add((TupleExpr) entry.getKey()); 1.273 - it.remove(); 1.274 - } 1.275 - 1.276 - TupleExpr replacement = orderedJoinArgs.get(0); 1.277 - for (int ii = 1; ii < orderedJoinArgs.size(); ii++) { 1.278 - replacement = new Join(replacement, orderedJoinArgs.get(ii)); 1.279 - } 1.280 - 1.281 - // Replace old join hierarchy 1.282 - node.replaceWith(replacement); 1.283 - 1.284 + else if(function instanceof SpatialRelationshipFunc) 1.285 + { 1.286 + return true; 1.287 } 1.288 - 1.289 - 1.290 - public boolean parentIsOptional(QueryModelNode node) 1.291 + else if(function instanceof SpatialPropertyFunc) //1 argument 1.292 { 1.293 - if(node.getParentNode() == null) 1.294 - { 1.295 - return false; 1.296 - } 1.297 - else if(node.getParentNode() instanceof LeftJoin) 1.298 - { 1.299 - return true; 1.300 - } 1.301 - else 1.302 - { 1.303 - return parentIsOptional(node.getParentNode()); 1.304 - } 1.305 + return true; 1.306 } 1.307 - 1.308 - /** 1.309 - * General Comment: If more than one function exists in the query and can be used to perform the join, no preference is shown 1.310 - * on which function will actually be used for this purpose. This could cause an issue if ST_Disjoint is the one finally used, 1.311 - * as the index won't be used for the evaluation in this case. Perhaps I should include some 'priority' 1.312 - */ 1.313 - @Override 1.314 - public void meet(Filter node) { 1.315 - 1.316 - /** 1.317 - * Filter node must not be in OPTIONAL clause! 1.318 - * After all, unneeded check. If an optional exists, the 'Filter' tuple expression 1.319 - * is removed and only the Function Calls remain 1.320 - */ 1.321 - if(!withinHaving(node)) 1.322 - { 1.323 - //if(!(node.getParentNode() instanceof LeftJoin)) 1.324 - //{ 1.325 - //XXX Ignore OR in Filters for now! (perhaps permanently) 1.326 - if(!(node.getCondition() instanceof Or)) 1.327 - { 1.328 - if(node.getCondition() instanceof FunctionCall) 1.329 - { 1.330 - //Only interested in spatial ones 1.331 - if(isRelevantSpatialFunc((FunctionCall) node.getCondition())) 1.332 - { 1.333 - //Have to retrieve all nested variables and other info 1.334 - 1.335 - //1.Retrieve varNames 1.336 - List<Var> varList = getFunctionCallVars((FunctionCall) node.getCondition()); 1.337 - 1.338 - //Cannot optimize buffer constructs when their 2nd argument is a 1.339 - //thematic var, because I can't manipulate the order of the 1.340 - //numeric_values table 1.341 - if(!problematicBuffer) 1.342 - { 1.343 - //XXX I cannot process cases involving more than 2 arguments in the spatial join! 1.344 - // They transcend the theta join level! 1.345 - // if(varList.size()<3) 1.346 - 1.347 - //if the arguments are not 2, I am essentially doing a selection! 1.348 - //No reason to push into optimizer then 1.349 - if(varList.size()==2) 1.350 - { 1.351 - //Add all important info about this spatial relationship to the appropriate structure 1.352 - //allSFilters.add(new SpatialFilterInfo(varList, (FunctionCall) node.getCondition())); 1.353 - Filter toEnter = node.clone(); 1.354 - 1.355 - /** 1.356 - * VERY CAREFUL HERE! 1.357 - * Reason I did this: If not, I would carry a copy of the whole expression for 1.358 - * every extra filter of my query! 1.359 - * -DUMMY-!!! 1.360 - */ 1.361 - StatementPattern t = new StatementPattern(); 1.362 - t.setSubjectVar(new Var("-dummy-")); 1.363 - t.setPredicateVar(new Var("-dummy-")); 1.364 - t.setObjectVar(new Var("-dummy-")); 1.365 - t.setScope(Scope.DEFAULT_CONTEXTS); 1.366 - toEnter.setArg(t); 1.367 - 1.368 - if(!allSFilters.containsKey(toEnter)) 1.369 - { 1.370 - allSFilters.put(toEnter,varList); 1.371 - } 1.372 - } 1.373 - problematicBuffer = false; 1.374 - } 1.375 - } 1.376 - } 1.377 - //Metrics 1.378 - //I have a similar problematic case with the one occurring in Buffer! 1.379 - //Cannot manipulate the join order when I am dealing with numerics! 1.380 - //Therefore, I cannot use a numeric field (a numeric var) to alter the join sequence 1.381 - else if(node.getCondition() instanceof Compare) 1.382 - { 1.383 - containsSpatial = false; 1.384 - List<Var> allVars = new ArrayList<Var>(getVarsInMetricOrProperty(node.getCondition())); 1.385 - if(containsSpatial&&optimizableMetricOrProperty) 1.386 - { 1.387 - //if the arguments are not 2, I am essentially doing a selection! 1.388 - //No reason to push into optimizer then 1.389 - if(allVars.size()==2) 1.390 - //if(allVars.size()<3) 1.391 - { 1.392 - //Add all important info about this spatial relationship to the appropriate structure 1.393 - //allSFilters.add(new SpatialFilterInfo(varList, (FunctionCall) node.getCondition())); 1.394 - Filter toEnter = node.clone(); 1.395 - 1.396 - StatementPattern t = new StatementPattern(); 1.397 - t.setSubjectVar(new Var("-dummy-")); 1.398 - t.setPredicateVar(new Var("-dummy-")); 1.399 - t.setObjectVar(new Var("-dummy-")); 1.400 - t.setScope(Scope.DEFAULT_CONTEXTS); 1.401 - toEnter.setArg(t); 1.402 - 1.403 - if(!allSFilters.containsKey(toEnter)) 1.404 - { 1.405 - allSFilters.put(toEnter,allVars); 1.406 - } 1.407 - } 1.408 - containsSpatial = false; 1.409 - } 1.410 - optimizableMetricOrProperty = true; 1.411 - } 1.412 - 1.413 - } 1.414 - //} 1.415 - } 1.416 - 1.417 - //Last thing to do is ensuring the entire tree is traversed 1.418 - node.visitChildren(this); 1.419 - 1.420 + else if(function instanceof SpatialMetricFunc) //Arguments # depends on the function selected 1.421 + { 1.422 + return true; 1.423 } 1.424 - 1.425 - 1.426 - /** 1.427 - * Helper Functions 1.428 - */ 1.429 - 1.430 - /** 1.431 - * Used to find out whether the Filter expr we are currently visiting is located inside 1.432 - * a HAVING clause. 1.433 - * 1.434 - * From what I have seen so far, it seems that if this is the case, its arg (or one of the following FILTER args in 1.435 - * the case of disjunction/conjunction) will be an Extension expr followed by a GROUP expr 1.436 - */ 1.437 - private boolean withinHaving(Filter expr) 1.438 - { 1.439 - if(expr.getArg() instanceof Extension) 1.440 - { 1.441 - return true; 1.442 - } 1.443 - else if(expr.getArg() instanceof Filter) 1.444 - { 1.445 - return withinHaving((Filter) expr.getArg()); 1.446 - } 1.447 - else 1.448 - { 1.449 - return false; 1.450 - } 1.451 - } 1.452 - 1.453 - private <L extends List<TupleExpr>> L getJoinArgs(TupleExpr tupleExpr, L joinArgs) { 1.454 - if (tupleExpr instanceof Join) { 1.455 - Join join = (Join)tupleExpr; 1.456 - if(getJoinArgs(join.getLeftArg(), joinArgs) == null) 1.457 - return null; 1.458 - if(getJoinArgs(join.getRightArg(), joinArgs) == null) 1.459 - return null; 1.460 - } 1.461 - else if(tupleExpr instanceof LeftJoin) 1.462 - { 1.463 - //Trying to avoid OPTIONAL clauses from passing 1.464 - return null; 1.465 - } 1.466 - else 1.467 - { 1.468 - joinArgs.add(tupleExpr); 1.469 - } 1.470 - 1.471 - return joinArgs; 1.472 - } 1.473 - 1.474 - private List<Var> getStatementPatternVars(TupleExpr tupleExpr) { 1.475 - List<StatementPattern> stPatterns = StatementPatternCollector.process(tupleExpr); 1.476 - List<Var> varList = new ArrayList<Var>(stPatterns.size() * 4); 1.477 - for (StatementPattern sp : stPatterns) { 1.478 - sp.getVars(varList); 1.479 - } 1.480 - return varList; 1.481 - } 1.482 - 1.483 - /** 1.484 - * spatialContent: Used to declare that this expression does include some spatial 1.485 - * content and an attempt should be made to use it in the joins' optimization process 1.486 - */ 1.487 - private Set<Var> getVarsInMetricOrProperty(ValueExpr expr) 1.488 - { 1.489 - Set<Var> allVars = new LinkedHashSet<Var>(); 1.490 - 1.491 - if(expr instanceof Compare) 1.492 - { 1.493 - allVars.addAll(getVarsInMetricOrProperty(((Compare) expr).getLeftArg())); 1.494 - allVars.addAll(getVarsInMetricOrProperty(((Compare) expr).getRightArg())); 1.495 - } 1.496 - else if(expr instanceof MathExpr) 1.497 - { 1.498 - allVars.addAll(getVarsInMetricOrProperty(((MathExpr) expr).getLeftArg())); 1.499 - allVars.addAll(getVarsInMetricOrProperty(((MathExpr) expr).getRightArg())); 1.500 - } 1.501 - else if(expr instanceof FunctionCall ) 1.502 - { 1.503 - if(isRelevantSpatialFunc((FunctionCall) expr)) 1.504 - { 1.505 - /** 1.506 - * There is a point in continuing the search recursively ONLY 1.507 - * if I reach this case. Otherwise, the function call 1.508 - * may not refer to a spatial function 1.509 - */ 1.510 - this.containsSpatial = true; 1.511 - allVars.addAll(getFunctionCallVars((FunctionCall) expr)); 1.512 - 1.513 - } 1.514 - } 1.515 - else if(expr instanceof Var) 1.516 - { 1.517 - if(!(expr.getParentNode() instanceof FunctionCall)) 1.518 - { 1.519 - //Cannot manipulate the join order when I am dealing with numerics! 1.520 - //Therefore, I cannot use a numeric field (a numeric var) to alter the join sequence 1.521 - this.optimizableMetricOrProperty = false; 1.522 - } 1.523 - if(!allVars.contains(expr)) 1.524 - { 1.525 - allVars.add((Var) expr); 1.526 - } 1.527 - } 1.528 - 1.529 - return allVars; 1.530 - } 1.531 - 1.532 - private boolean isRelevantSpatialFunc(FunctionCall functionCall) 1.533 - { 1.534 - Function function = FunctionRegistry.getInstance().get(functionCall.getURI()); 1.535 - if(function instanceof SpatialConstructFunc) 1.536 - { 1.537 - //TODO may have to comment this part again 1.538 - //uncommented because I use this function in the case of metrics 1.539 - return true; 1.540 - } 1.541 - else if(function instanceof SpatialRelationshipFunc) 1.542 - { 1.543 - return true; 1.544 - } 1.545 - else if(function instanceof SpatialPropertyFunc) //1 argument 1.546 - { 1.547 - return true; 1.548 - } 1.549 - else if(function instanceof SpatialMetricFunc) //Arguments # depends on the function selected 1.550 - { 1.551 - return true; 1.552 - } 1.553 - return false; 1.554 - } 1.555 - 1.556 - private List<Var> getFunctionCallVars(FunctionCall functionCall) { 1.557 - List<Var> varList = new ArrayList<Var>(); 1.558 - int argList = 0; 1.559 - for(ValueExpr expr : functionCall.getArgs()) 1.560 - { 1.561 - argList++; 1.562 - if(expr instanceof Var) 1.563 - { 1.564 - // if(!existingVars.contains(((Var) expr).getName())) 1.565 - // { 1.566 - // existingVars.add(((Var) expr).getName()); 1.567 - // } 1.568 - 1.569 - if(!varList.contains(expr)) 1.570 - { 1.571 - //Was using this code when I tried to incorporate the Buffer case buffer(?Spatial,?thematic) 1.572 - if(argList == 2 && functionCall.getURI().equals("http://strdf.di.uoa.gr/ontology#buffer")) 1.573 - { 1.574 - problematicBuffer = true; 1.575 - } 1.576 - varList.add((Var) expr); 1.577 - } 1.578 - 1.579 - } 1.580 - else if(expr instanceof FunctionCall) 1.581 - { 1.582 - varList.addAll(getFunctionCallVars((FunctionCall) expr)); 1.583 - } 1.584 - //TODO Should I add any additional cases? I don't think so 1.585 - else 1.586 - { 1.587 - continue; 1.588 - } 1.589 - } 1.590 - return varList; 1.591 - } 1.592 - 1.593 - /** 1.594 - * Both lists belong to either a thematic node (St.Pattern) or a spatial node (Filter) 1.595 - * Comparing the vars with each other to discover links of the query graph 1.596 - * @param list1 1.597 - * @param list2 1.598 - * @return 1.599 - */ 1.600 - private int sameVar(List<Var> list1, List<Var> list2) 1.601 - { 1.602 - for(Var var : list1) 1.603 - { 1.604 - if(list2.contains(var)) 1.605 - { 1.606 - return 1; 1.607 - } 1.608 - } 1.609 - 1.610 - return 0; 1.611 - } 1.612 - 1.613 - 1.614 - 1.615 - 1.616 - 1.617 - //Input: a single line of the table 1.618 - //NOTE: NO LOOPS! CAREFUL!! 1.619 - private boolean createOrderedJoins(int table[][], int lineToScan,int columnToSkip, 1.620 - int pathLen, Set<Var> varsTillNow, List<Integer> tempList, List<Integer> pathList, List<Integer> finalList) 1.621 - { 1.622 - boolean success = false; 1.623 - int dims = table.length; 1.624 - 1.625 - int j; 1.626 - 1.627 - //dims: all arguments 1.628 - for(j = 0; j < dims; j++) 1.629 - { 1.630 - if(j == columnToSkip) 1.631 - { 1.632 - continue; 1.633 - } 1.634 - 1.635 - //A connection exists! 1.636 - if(table[lineToScan][j]>0) 1.637 - { 1.638 - //Don't want my graph to have circles!!! 1.639 - if(!tempList.contains(j)&&!pathList.contains(j)) 1.640 - { 1.641 - if(j >= thematicJoinsSize) //aka if(allSFilters.size() > 0) 1.642 - { 1.643 - List<Var> thisFilterVars = null; 1.644 - int count = 0; 1.645 - for(List<Var> vars : allSFilters.values()) 1.646 - { 1.647 - if(count == j - thematicJoinsSize) 1.648 - { 1.649 - thisFilterVars = vars; 1.650 - break; 1.651 - } 1.652 - count++; 1.653 - } 1.654 - if(!varsTillNow.isEmpty()) 1.655 - { 1.656 - if(varsTillNow.containsAll(thisFilterVars)) 1.657 - { 1.658 - continue; 1.659 - } 1.660 - } 1.661 - 1.662 - //varsTillNow.add(thisFilterVars.get(1)); 1.663 - varsTillNow.addAll(thisFilterVars); 1.664 - 1.665 - } 1.666 - 1.667 - tempList.add((Integer)j); 1.668 - pathLen++; 1.669 - if(pathLen == dims) 1.670 - { 1.671 - //End of recursion 1.672 - pathList.addAll(tempList); 1.673 - tempList.clear(); 1.674 - finalList.clear(); 1.675 - finalList.addAll(pathList); 1.676 - 1.677 - return true; 1.678 - } 1.679 - 1.680 - //Recurse 1.681 - success = createOrderedJoins(table, j, lineToScan, pathLen, varsTillNow, tempList, pathList, finalList); 1.682 - 1.683 - //Success = true => recursion ended with pathLen = maxLen 1.684 - if(success) 1.685 - { 1.686 - return true; 1.687 - } 1.688 - else 1.689 - { 1.690 - //end of a path originating from this node was found -> find an additional path (if exists) 1.691 - continue; 1.692 - } 1.693 - } 1.694 - } 1.695 - } 1.696 - //To reach this place means the end of a path was found 1.697 - pathList.addAll(tempList); 1.698 - tempList.clear(); 1.699 - if(pathList.size() > finalList.size()) 1.700 - { 1.701 - finalList.clear(); 1.702 - finalList.addAll(pathList); 1.703 - if(finalList.size() == dims) 1.704 - { 1.705 - return true; 1.706 - } 1.707 - } 1.708 - return false; 1.709 - } 1.710 - 1.711 + return false; 1.712 } 1.713 1.714 1.715 + @Override 1.716 + public String getClassName() { 1.717 + // TODO Auto-generated method stub 1.718 + return this.getClass().getCanonicalName(); 1.719 + } 1.720 + 1.721 }
2.1 --- a/evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/TemporalJoinOptimizer.java Fri May 10 16:10:00 2013 +0300 2.2 +++ b/evaluation/src/main/java/org/openrdf/query/algebra/evaluation/impl/TemporalJoinOptimizer.java Fri May 10 19:27:31 2013 +0300 2.3 @@ -3,7 +3,7 @@ 2.4 * License, v. 2.0. If a copy of the MPL was not distributed with this 2.5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 2.6 * 2.7 - * Copyright (C) 2010, 2011, 2012, Pyravlos Team 2.8 + * Copyright (C) 2013 Pyravlos Team 2.9 * 2.10 * http://www.strabon.di.uoa.gr/ 2.11 */ 2.12 @@ -42,9 +42,12 @@ 2.13 /** 2.14 * A query optimizer that re-orders nested Joins. 2.15 * 2.16 + * @author Konstantina Bereta <Konstantina.Bereta@di.uoa.gr> 2.17 + * 2.18 + * based on the code of the SpatialJoinOptimizer by 2.19 * @author Manos Karpathiotakis <mk@di.uoa.gr> 2.20 */ 2.21 -public class TemporalJoinOptimizer 2.22 +public class TemporalJoinOptimizer extends SpatioTemporalJoinOptimizer 2.23 //implements QueryOptimizer //Removed it consciously 2.24 { 2.25 2.26 @@ -60,674 +63,29 @@ 2.27 tupleExpr.visit(new JoinVisitor(temporalJoins)); 2.28 } 2.29 2.30 - protected class JoinVisitor extends QueryModelVisitorBase<RuntimeException> { 2.31 - 2.32 - 2.33 - 2.34 - public JoinVisitor(List<TupleExpr> temporalJoins) { 2.35 - super(); 2.36 - this.temporalJoins = temporalJoins; 2.37 + 2.38 + 2.39 + protected boolean isRelevantSTFunc(FunctionCall functionCall) 2.40 + { 2.41 + Function function = FunctionRegistry.getInstance().get(functionCall.getURI()); 2.42 + if(function instanceof org.openrdf.query.algebra.evaluation.function.temporal.stsparql.construct.TemporalConstructFunc ) 2.43 + { 2.44 + //TODO may have to comment this part again 2.45 + //uncommented because I use this function in the case of metrics 2.46 + return true; 2.47 } 2.48 - 2.49 - 2.50 - private List<TupleExpr> temporalJoins; 2.51 - //buffer with a var as a second argument 2.52 - private boolean problematicBuffer = false; 2.53 - 2.54 - //indicates whether a metric expression contains a temporal function call 2.55 - private boolean containsTemporal = false; 2.56 - private boolean optimizableMetricOrProperty = true; 2.57 - 2.58 - private int thematicJoinsSize = 0; 2.59 - 2.60 - 2.61 - Map<TupleExpr, List<Var>> temporalFilters = new HashMap<TupleExpr, List<Var>>(); 2.62 - 2.63 - @Override 2.64 - public void meet(Join node) { 2.65 - 2.66 - //XXX NOTE: NOT OPTIMIZING CONTENTS OF OPTIONAL CLAUSE!!! 2.67 - //Reason1: Errors occurred in the condition of the LeftJoin containing the optional subgraph 2.68 - 2.69 - //Not as successful as I hoped. Some OPTIONAL clauses may pass 2.70 - if(parentIsOptional(node)) 2.71 - { 2.72 - return; 2.73 - } 2.74 - // if(node.getParentNode() instanceof LeftJoin) 2.75 - // { 2.76 - // return; 2.77 - // } 2.78 - 2.79 - // Recursively get the join arguments 2.80 - List<TupleExpr> joinArgs = getJoinArgs(node, new ArrayList<TupleExpr>()); 2.81 - 2.82 - if(joinArgs == null) 2.83 - { 2.84 - //2nd mechanism to avoid OPTIONAL clauses from passing 2.85 - return; 2.86 - } 2.87 - 2.88 - 2.89 - Map<TupleExpr, List<Var>> varsMap = new /*Linked*/HashMap<TupleExpr, List<Var>>(); 2.90 - 2.91 - for (TupleExpr tupleExpr : joinArgs) { 2.92 - varsMap.put(tupleExpr, getStatementPatternVars(tupleExpr)); 2.93 - 2.94 - } 2.95 - 2.96 - //Now I have all the info I need. Just need to structure it efficiently 2.97 - int allNodes = varsMap.size() + temporalFilters.size(); 2.98 - thematicJoinsSize = varsMap.size(); 2.99 - //careful with positions on the diagonal! Do not utilize them! 2.100 - int joinsGraph[][] = new int[allNodes][allNodes]; 2.101 - 2.102 - //prints for debug 2.103 - // Set<TupleExpr> allExprs = varsMap.keySet(); 2.104 - // System.out.println(allExprs.toString()); 2.105 - // 2.106 - // Set<TupleExpr> allFilters = temporalFilters.keySet(); 2.107 - // System.out.println(allFilters.toString()); 2.108 - 2.109 - //Thematic part first 2.110 - int i = 0; 2.111 - 2.112 - for(List<Var> listHorizontal : varsMap.values()) 2.113 - { 2.114 - int j = 0; 2.115 - int k = 0; 2.116 - 2.117 - //Other thematics 2.118 - for(List<Var> listVertical : varsMap.values()) 2.119 - { 2.120 - if(i==j) 2.121 - { 2.122 - j++; 2.123 - continue; 2.124 - } 2.125 - 2.126 - 2.127 - joinsGraph[i][j] = sameVar(listHorizontal, listVertical); 2.128 - 2.129 - j++; 2.130 - } 2.131 - 2.132 - //Temporals 2.133 - for(List<Var> listVertical : temporalFilters.values()) 2.134 - { 2.135 - 2.136 - joinsGraph[i][k+varsMap.size()] = sameVar(listHorizontal, listVertical); 2.137 - 2.138 - k++; 2.139 - } 2.140 - 2.141 - i++; 2.142 - } 2.143 - 2.144 - //Now for the temporal horizontal nodes 2.145 - i = varsMap.size(); 2.146 - for(List<Var> listHorizontal : temporalFilters.values()) 2.147 - { 2.148 - int j = 0; 2.149 - int k = 0; 2.150 - 2.151 - //Other thematics 2.152 - for(List<Var> listVertical : varsMap.values()) 2.153 - { 2.154 - 2.155 - joinsGraph[i][j] = sameVar(listHorizontal, listVertical); 2.156 - 2.157 - j++; 2.158 - } 2.159 - 2.160 - //Temporals 2.161 - for(List<Var> listVertical : temporalFilters.values()) 2.162 - { 2.163 - if(i==k+varsMap.size()) 2.164 - { 2.165 - k++; 2.166 - continue; 2.167 - } 2.168 - 2.169 - joinsGraph[i][k+varsMap.size()] =sameVar(listHorizontal, listVertical); 2.170 - 2.171 - k++; 2.172 - } 2.173 - 2.174 - i++; 2.175 - } 2.176 - 2.177 - //Checking graph to be sure 2.178 - /* 2.179 - for(int a = 0; a < allNodes; a++) 2.180 - { 2.181 - for(int b = 0; b < allNodes; b++) 2.182 - { 2.183 - System.out.print(joinsGraph[a][b]+" "); 2.184 - 2.185 - } 2.186 - System.out.println(""); 2.187 - } 2.188 - */ 2.189 - 2.190 - //Time to construct ordered sequence of joins + filters 2.191 - List<TupleExpr> orderedJoinArgs = new ArrayList<TupleExpr>(allNodes); 2.192 - //maybe I won't need all the positions -> some temporal joins may not be utilized 2.193 - List<Integer> tempList = new ArrayList<Integer>(allNodes); 2.194 - List<Integer> pathList = new ArrayList<Integer>(); 2.195 - List<Integer> finalList = new ArrayList<Integer>(); 2.196 - Set<Var> varsTillNow = new LinkedHashSet<Var>(); 2.197 - for(int row = 0 ; row < allNodes ; row++) 2.198 - { 2.199 - tempList.add(row); 2.200 - createOrderedJoins(joinsGraph, row, row, 1, varsTillNow, tempList, pathList, finalList); 2.201 - pathList.clear(); 2.202 - if(finalList.size() == allNodes) 2.203 - { 2.204 - break; 2.205 - } 2.206 - 2.207 - } 2.208 - 2.209 - /* 2.210 - System.out.println("*--REWRITTEN TREE--**"); 2.211 - System.out.println(finalList.toString()); 2.212 - */ 2.213 - 2.214 - int varsMapSize = varsMap.size(); 2.215 - for(Integer position : finalList) 2.216 - { 2.217 - if(position<varsMapSize)//thematic! 2.218 - { 2.219 - int count = 0; 2.220 - Iterator it = varsMap.entrySet().iterator(); 2.221 - 2.222 - while (it.hasNext()) 2.223 - { 2.224 - { 2.225 - Map.Entry entry = (Map.Entry)it.next(); 2.226 - if(count == position) 2.227 - { 2.228 - orderedJoinArgs.add((TupleExpr) entry.getKey()); 2.229 - 2.230 - it.remove(); 2.231 - varsMapSize--; 2.232 - 2.233 - for(int fix = 0 ; fix < finalList.size(); fix++) 2.234 - { 2.235 - if(finalList.get(fix) > position) 2.236 - { 2.237 - int reduced = finalList.get(fix) - 1; 2.238 - finalList.set(fix, reduced); 2.239 - 2.240 - } 2.241 - } 2.242 - break; 2.243 - } 2.244 - count++; 2.245 - } 2.246 - } 2.247 - } 2.248 - else//temporal! 2.249 - { 2.250 - int count = 0; 2.251 - Iterator it = temporalFilters.entrySet().iterator(); 2.252 - while (it.hasNext()) 2.253 - { 2.254 - { 2.255 - Map.Entry entry = (Map.Entry)it.next(); 2.256 - if(count == position - varsMapSize) 2.257 - { 2.258 - //If I keep record of this entry, I can use the info later to avoid duplicate filters 2.259 - temporalJoins.add((TupleExpr) entry.getKey()); 2.260 - // 2.261 - orderedJoinArgs.add((TupleExpr) entry.getKey()); 2.262 - it.remove(); 2.263 - for(int fix = 0 ; fix < finalList.size(); fix++) 2.264 - { 2.265 - if(finalList.get(fix) > position) 2.266 - { 2.267 - int reduced = finalList.get(fix) - 1; 2.268 - finalList.set(fix, reduced); 2.269 - } 2.270 - } 2.271 - break; 2.272 - } 2.273 - count++; 2.274 - } 2.275 - } 2.276 - } 2.277 - 2.278 - } 2.279 - //Must take care of the remainders as well! 2.280 - Iterator it = varsMap.entrySet().iterator(); 2.281 - while (it.hasNext()) 2.282 - { 2.283 - Map.Entry entry = (Map.Entry)it.next(); 2.284 - orderedJoinArgs.add((TupleExpr) entry.getKey()); 2.285 - it.remove(); 2.286 - } 2.287 - 2.288 - TupleExpr replacement = orderedJoinArgs.get(0); 2.289 - for (int ii = 1; ii < orderedJoinArgs.size(); ii++) { 2.290 - replacement = new Join(replacement, orderedJoinArgs.get(ii)); 2.291 - } 2.292 - 2.293 - // Replace old join hierarchy 2.294 - node.replaceWith(replacement); 2.295 - 2.296 + else if(function instanceof TemporalRelationFunc) 2.297 + { 2.298 + return true; 2.299 } 2.300 - 2.301 - 2.302 - public boolean parentIsOptional(QueryModelNode node) 2.303 - { 2.304 - if(node.getParentNode() == null) 2.305 - { 2.306 - return false; 2.307 - } 2.308 - else if(node.getParentNode() instanceof LeftJoin) 2.309 - { 2.310 - return true; 2.311 - } 2.312 - else 2.313 - { 2.314 - return parentIsOptional(node.getParentNode()); 2.315 - } 2.316 - } 2.317 - 2.318 - /** 2.319 - * General Comment: If more than one function exists in the query and can be used to perform the join, no preference is shown 2.320 - * on which function will actually be used for this purpose. This could cause an issue if ST_Disjoint is the one finally used, 2.321 - * as the index won't be used for the evaluation in this case. Perhaps I should include some 'priority' 2.322 - */ 2.323 - @Override 2.324 - public void meet(Filter node) { 2.325 - 2.326 - /** 2.327 - * Filter node must not be in OPTIONAL clause! 2.328 - * After all, unneeded check. If an optional exists, the 'Filter' tuple expression 2.329 - * is removed and only the Function Calls remain 2.330 - */ 2.331 - if(!withinHaving(node)) 2.332 - { 2.333 - //if(!(node.getParentNode() instanceof LeftJoin)) 2.334 - //{ 2.335 - //XXX Ignore OR in Filters for now! (perhaps permanently) 2.336 - if(!(node.getCondition() instanceof Or)) 2.337 - { 2.338 - if(node.getCondition() instanceof FunctionCall) 2.339 - { 2.340 - //Only interested in temporal ones 2.341 - if(isRelevantTemporalFunc((FunctionCall) node.getCondition())) 2.342 - { 2.343 - //Have to retrieve all nested variables and other info 2.344 - 2.345 - //1.Retrieve varNames 2.346 - List<Var> varList = getFunctionCallVars((FunctionCall) node.getCondition()); 2.347 - 2.348 - //Cannot optimize buffer constructs when their 2nd argument is a 2.349 - //thematic var, because I can't manipulate the order of the 2.350 - //numeric_values table 2.351 - if(!problematicBuffer) 2.352 - { 2.353 - //XXX I cannot process cases involving more than 2 arguments in the temporal join! 2.354 - // They transcend the theta join level! 2.355 - // if(varList.size()<3) 2.356 - 2.357 - //if the arguments are not 2, I am essentially doing a selection! 2.358 - //No reason to push into optimizer then 2.359 - if(varList.size()==2) 2.360 - { 2.361 - //Add all important info about this temporal relationship to the appropriate structure 2.362 - //temporalFilters.add(new TemporalFilterInfo(varList, (FunctionCall) node.getCondition())); 2.363 - Filter toEnter = node.clone(); 2.364 - 2.365 - /** 2.366 - * VERY CAREFUL HERE! 2.367 - * Reason I did this: If not, I would carry a copy of the whole expression for 2.368 - * every extra filter of my query! 2.369 - * -DUMMY-!!! 2.370 - */ 2.371 - StatementPattern t = new StatementPattern(); 2.372 - t.setSubjectVar(new Var("-dummy-temporal")); 2.373 - t.setPredicateVar(new Var("-dummy-temporal")); 2.374 - t.setObjectVar(new Var("-dummy-temporal")); 2.375 - t.setScope(Scope.DEFAULT_CONTEXTS); 2.376 - toEnter.setArg(t); 2.377 - 2.378 - if(!temporalFilters.containsKey(toEnter)) 2.379 - { 2.380 - temporalFilters.put(toEnter,varList); 2.381 - } 2.382 - } 2.383 - problematicBuffer = false; 2.384 - } 2.385 - } 2.386 - } 2.387 - //Metrics 2.388 - //I have a similar problematic case with the one occurring in Buffer! 2.389 - //Cannot manipulate the join order when I am dealing with numerics! 2.390 - //Therefore, I cannot use a numeric field (a numeric var) to alter the join sequence 2.391 - else if(node.getCondition() instanceof Compare) 2.392 - { 2.393 - containsTemporal = false; 2.394 - List<Var> allVars = new ArrayList<Var>(getVarsInMetricOrProperty(node.getCondition())); 2.395 - if(containsTemporal&&optimizableMetricOrProperty) 2.396 - { 2.397 - //if the arguments are not 2, I am essentially doing a selection! 2.398 - //No reason to push into optimizer then 2.399 - if(allVars.size()==2) 2.400 - //if(allVars.size()<3) 2.401 - { 2.402 - //Add all important info about this temporal relationship to the appropriate structure 2.403 - //temporalFilters.add(new TemporalFilterInfo(varList, (FunctionCall) node.getCondition())); 2.404 - Filter toEnter = node.clone(); 2.405 - 2.406 - StatementPattern t = new StatementPattern(); 2.407 - t.setSubjectVar(new Var("-dummy-")); 2.408 - t.setPredicateVar(new Var("-dummy-")); 2.409 - t.setObjectVar(new Var("-dummy-")); 2.410 - t.setScope(Scope.DEFAULT_CONTEXTS); 2.411 - toEnter.setArg(t); 2.412 - 2.413 - if(!temporalFilters.containsKey(toEnter)) 2.414 - { 2.415 - temporalFilters.put(toEnter,allVars); 2.416 - } 2.417 - } 2.418 - containsTemporal = false; 2.419 - } 2.420 - optimizableMetricOrProperty = true; 2.421 - } 2.422 - 2.423 - } 2.424 - //} 2.425 - } 2.426 - 2.427 - //Last thing to do is ensuring the entire tree is traversed 2.428 - node.visitChildren(this); 2.429 - 2.430 - } 2.431 - 2.432 - 2.433 - /** 2.434 - * Helper Functions 2.435 - */ 2.436 - 2.437 - /** 2.438 - * Used to find out whether the Filter expr we are currently visiting is located inside 2.439 - * a HAVING clause. 2.440 - * 2.441 - * From what I have seen so far, it seems that if this is the case, its arg (or one of the following FILTER args in 2.442 - * the case of disjunction/conjunction) will be an Extension expr followed by a GROUP expr 2.443 - */ 2.444 - private boolean withinHaving(Filter expr) 2.445 - { 2.446 - if(expr.getArg() instanceof Extension) 2.447 - { 2.448 - return true; 2.449 - } 2.450 - else if(expr.getArg() instanceof Filter) 2.451 - { 2.452 - return withinHaving((Filter) expr.getArg()); 2.453 - } 2.454 - else 2.455 - { 2.456 - return false; 2.457 - } 2.458 - } 2.459 - 2.460 - private <L extends List<TupleExpr>> L getJoinArgs(TupleExpr tupleExpr, L joinArgs) { 2.461 - if (tupleExpr instanceof Join) { 2.462 - Join join = (Join)tupleExpr; 2.463 - if(getJoinArgs(join.getLeftArg(), joinArgs) == null) 2.464 - return null; 2.465 - if(getJoinArgs(join.getRightArg(), joinArgs) == null) 2.466 - return null; 2.467 - } 2.468 - else if(tupleExpr instanceof LeftJoin) 2.469 - { 2.470 - //Trying to avoid OPTIONAL clauses from passing 2.471 - return null; 2.472 - } 2.473 - else 2.474 - { 2.475 - joinArgs.add(tupleExpr); 2.476 - } 2.477 - 2.478 - return joinArgs; 2.479 - } 2.480 - 2.481 - private List<Var> getStatementPatternVars(TupleExpr tupleExpr) { 2.482 - List<StatementPattern> stPatterns = StatementPatternCollector.process(tupleExpr); 2.483 - List<Var> varList = new ArrayList<Var>(stPatterns.size() * 4); 2.484 - for (StatementPattern sp : stPatterns) { 2.485 - sp.getVars(varList); 2.486 - } 2.487 - return varList; 2.488 - } 2.489 - 2.490 - /** 2.491 - * temporalContent: Used to declare that this expression does include some temporal 2.492 - * content and an attempt should be made to use it in the joins' optimization process 2.493 - */ 2.494 - private Set<Var> getVarsInMetricOrProperty(ValueExpr expr) 2.495 - { 2.496 - Set<Var> allVars = new LinkedHashSet<Var>(); 2.497 - 2.498 - if(expr instanceof Compare) 2.499 - { 2.500 - allVars.addAll(getVarsInMetricOrProperty(((Compare) expr).getLeftArg())); 2.501 - allVars.addAll(getVarsInMetricOrProperty(((Compare) expr).getRightArg())); 2.502 - } 2.503 - else if(expr instanceof MathExpr) 2.504 - { 2.505 - allVars.addAll(getVarsInMetricOrProperty(((MathExpr) expr).getLeftArg())); 2.506 - allVars.addAll(getVarsInMetricOrProperty(((MathExpr) expr).getRightArg())); 2.507 - } 2.508 - else if(expr instanceof FunctionCall ) 2.509 - { 2.510 - if(isRelevantTemporalFunc((FunctionCall) expr)) 2.511 - { 2.512 - /** 2.513 - * There is a point in continuing the search recursively ONLY 2.514 - * if I reach this case. Otherwise, the function call 2.515 - * may not refer to a temporal function 2.516 - */ 2.517 - this.containsTemporal = true; 2.518 - allVars.addAll(getFunctionCallVars((FunctionCall) expr)); 2.519 - 2.520 - } 2.521 - } 2.522 - else if(expr instanceof Var) 2.523 - { 2.524 - if(!(expr.getParentNode() instanceof FunctionCall)) 2.525 - { 2.526 - //Cannot manipulate the join order when I am dealing with numerics! 2.527 - //Therefore, I cannot use a numeric field (a numeric var) to alter the join sequence 2.528 - this.optimizableMetricOrProperty = false; 2.529 - } 2.530 - if(!allVars.contains(expr)) 2.531 - { 2.532 - allVars.add((Var) expr); 2.533 - } 2.534 - } 2.535 - 2.536 - return allVars; 2.537 - } 2.538 - 2.539 - private boolean isRelevantTemporalFunc(FunctionCall functionCall) 2.540 - { 2.541 - Function function = FunctionRegistry.getInstance().get(functionCall.getURI()); 2.542 - if(function instanceof org.openrdf.query.algebra.evaluation.function.temporal.stsparql.construct.TemporalConstructFunc ) 2.543 - { 2.544 - //TODO may have to comment this part again 2.545 - //uncommented because I use this function in the case of metrics 2.546 - return true; 2.547 - } 2.548 - else if(function instanceof TemporalRelationFunc) 2.549 - { 2.550 - return true; 2.551 - } 2.552 - return false; 2.553 - } 2.554 - 2.555 - private List<Var> getFunctionCallVars(FunctionCall functionCall) { 2.556 - List<Var> varList = new ArrayList<Var>(); 2.557 - int argList = 0; 2.558 - for(ValueExpr expr : functionCall.getArgs()) 2.559 - { 2.560 - argList++; 2.561 - if(expr instanceof Var) 2.562 - { 2.563 - // if(!existingVars.contains(((Var) expr).getName())) 2.564 - // { 2.565 - // existingVars.add(((Var) expr).getName()); 2.566 - // } 2.567 - 2.568 - if(!varList.contains(expr)) 2.569 - { 2.570 - //Was using this code when I tried to incorporate the Buffer case buffer(?Temporal,?thematic) 2.571 - if(argList == 2 && functionCall.getURI().equals("http://strdf.di.uoa.gr/ontology#buffer")) 2.572 - { 2.573 - problematicBuffer = true; 2.574 - } 2.575 - varList.add((Var) expr); 2.576 - } 2.577 - 2.578 - } 2.579 - else if(expr instanceof FunctionCall) 2.580 - { 2.581 - varList.addAll(getFunctionCallVars((FunctionCall) expr)); 2.582 - } 2.583 - //TODO Should I add any additional cases? I don't think so 2.584 - else 2.585 - { 2.586 - continue; 2.587 - } 2.588 - } 2.589 - return varList; 2.590 - } 2.591 - 2.592 - /** 2.593 - * Both lists belong to either a thematic node (St.Pattern) or a temporal node (Filter) 2.594 - * Comparing the vars with each other to discover links of the query graph 2.595 - * @param list1 2.596 - * @param list2 2.597 - * @return 2.598 - */ 2.599 - private int sameVar(List<Var> list1, List<Var> list2) 2.600 - { 2.601 - for(Var var : list1) 2.602 - { 2.603 - if(list2.contains(var)) 2.604 - { 2.605 - return 1; 2.606 - } 2.607 - } 2.608 - 2.609 - return 0; 2.610 - } 2.611 - 2.612 - 2.613 - 2.614 - 2.615 - 2.616 - //Input: a single line of the table 2.617 - //NOTE: NO LOOPS! CAREFUL!! 2.618 - private boolean createOrderedJoins(int table[][], int lineToScan,int columnToSkip, 2.619 - int pathLen, Set<Var> varsTillNow, List<Integer> tempList, List<Integer> pathList, List<Integer> finalList) 2.620 - { 2.621 - boolean success = false; 2.622 - int dims = table.length; 2.623 - 2.624 - int j; 2.625 - 2.626 - //dims: all arguments 2.627 - for(j = 0; j < dims; j++) 2.628 - { 2.629 - if(j == columnToSkip) 2.630 - { 2.631 - continue; 2.632 - } 2.633 - 2.634 - //A connection exists! 2.635 - if(table[lineToScan][j]>0) 2.636 - { 2.637 - //Don't want my graph to have circles!!! 2.638 - if(!tempList.contains(j)&&!pathList.contains(j)) 2.639 - { 2.640 - if(j >= thematicJoinsSize) //aka if(temporalFilters.size() > 0) 2.641 - { 2.642 - List<Var> thisFilterVars = null; 2.643 - int count = 0; 2.644 - for(List<Var> vars : temporalFilters.values()) 2.645 - { 2.646 - if(count == j - thematicJoinsSize) 2.647 - { 2.648 - thisFilterVars = vars; 2.649 - break; 2.650 - } 2.651 - count++; 2.652 - } 2.653 - if(!varsTillNow.isEmpty()) 2.654 - { 2.655 - if(varsTillNow.containsAll(thisFilterVars)) 2.656 - { 2.657 - continue; 2.658 - } 2.659 - } 2.660 - 2.661 - //varsTillNow.add(thisFilterVars.get(1)); 2.662 - varsTillNow.addAll(thisFilterVars); 2.663 - 2.664 - } 2.665 - 2.666 - tempList.add((Integer)j); 2.667 - pathLen++; 2.668 - if(pathLen == dims) 2.669 - { 2.670 - //End of recursion 2.671 - pathList.addAll(tempList); 2.672 - tempList.clear(); 2.673 - finalList.clear(); 2.674 - finalList.addAll(pathList); 2.675 - 2.676 - return true; 2.677 - } 2.678 - 2.679 - //Recurse 2.680 - success = createOrderedJoins(table, j, lineToScan, pathLen, varsTillNow, tempList, pathList, finalList); 2.681 - 2.682 - //Success = true => recursion ended with pathLen = maxLen 2.683 - if(success) 2.684 - { 2.685 - return true; 2.686 - } 2.687 - else 2.688 - { 2.689 - //end of a path originating from this node was found -> find an additional path (if exists) 2.690 - continue; 2.691 - } 2.692 - } 2.693 - } 2.694 - } 2.695 - //To reach this place means the end of a path was found 2.696 - pathList.addAll(tempList); 2.697 - tempList.clear(); 2.698 - if(pathList.size() > finalList.size()) 2.699 - { 2.700 - finalList.clear(); 2.701 - finalList.addAll(pathList); 2.702 - if(finalList.size() == dims) 2.703 - { 2.704 - return true; 2.705 - } 2.706 - } 2.707 - return false; 2.708 - } 2.709 - 2.710 + return false; 2.711 } 2.712 2.713 + @Override 2.714 + public String getClassName() { 2.715 + // TODO Auto-generated method stub 2.716 + return this.getClass().getCanonicalName(); 2.717 + } 2.718 + 2.719 2.720 }
3.1 --- a/generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBQueryOptimizer.java Fri May 10 16:10:00 2013 +0300 3.2 +++ b/generaldb/src/main/java/org/openrdf/sail/generaldb/optimizers/GeneralDBQueryOptimizer.java Fri May 10 19:27:31 2013 +0300 3.3 @@ -119,7 +119,7 @@ 3.4 //XXX 3.5 new SpatialJoinOptimizer().optimize(expr, dataset, bindings,spatialJoins); 3.6 3.7 - new TemporalJoinOptimizer().optimize(expr, dataset, bindings, temporalJoins); 3.8 + //new TemporalJoinOptimizer().optimize(expr, dataset, bindings, temporalJoins); 3.9 } 3.10 3.11 protected void rdbmsOptimizations(TupleExpr expr, Dataset dataset, BindingSet bindings) {