blob: c970b0e031d3e6ad050ed0716656a37561abf2a3 [file] [log] [blame]
package org.apache.rya.indexing.IndexPlanValidator;
/*
* 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.
*/
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet;
import org.eclipse.rdf4j.query.algebra.Filter;
import org.eclipse.rdf4j.query.algebra.StatementPattern;
import org.eclipse.rdf4j.query.algebra.TupleExpr;
import org.eclipse.rdf4j.query.algebra.ValueConstant;
import org.eclipse.rdf4j.query.algebra.Var;
import org.eclipse.rdf4j.query.algebra.helpers.AbstractQueryModelVisitor;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
public class VarConstantIndexListPruner implements IndexListPruner {
private Map<String, Integer> queryConstantMap;
private int querySpCount;
private int queryFilterCount;
public VarConstantIndexListPruner(TupleExpr te) {
ConstantCollector cc = new ConstantCollector();
te.visit(cc);
this.queryConstantMap = cc.getConstantMap();
querySpCount = cc.getSpCount();
queryFilterCount = cc.getFilterCount();
}
@Override
public List<ExternalTupleSet> getRelevantIndices(List<ExternalTupleSet> indexList) {
List<ExternalTupleSet> relIndexSet = new ArrayList<>();
for (ExternalTupleSet e : indexList) {
if (isRelevant(e.getTupleExpr())) {
relIndexSet.add(e);
}
}
return relIndexSet;
}
private boolean isRelevant(TupleExpr index) {
ConstantCollector cc = new ConstantCollector();
index.visit(cc);
Map<String, Integer> indexConstantMap = cc.getConstantMap();
int indexSpCount = cc.getSpCount();
int indexFilterCount = cc.getFilterCount();
Set<String> indexConstants = indexConstantMap.keySet();
if (indexSpCount > querySpCount || indexFilterCount > queryFilterCount
|| !Sets.intersection(indexConstants, queryConstantMap.keySet()).equals(indexConstants)) {
return false;
}
for (String s : indexConstants) {
if (indexConstantMap.get(s) > queryConstantMap.get(s)) {
return false;
}
}
return true;
}
private static class ConstantCollector extends AbstractQueryModelVisitor<RuntimeException> {
private Map<String, Integer> constantMap = Maps.newHashMap();
private int spCount = 0;
private int filterCount = 0;
@Override
public void meet(StatementPattern node) throws RuntimeException {
spCount++;
super.meet(node);
}
@Override
public void meet(Filter node) throws RuntimeException {
filterCount++;
super.meet(node);
}
@Override
public void meet(Var node) throws RuntimeException {
if (node.isConstant()) {
String key = node.getValue().toString();
if(constantMap.containsKey(key)){
int count = constantMap.get(key);
count += 1;
constantMap.put(key, count);
} else {
constantMap.put(key, 1);
}
}
}
@Override
public void meet(ValueConstant node) throws RuntimeException {
String key = node.getValue().toString();
if(constantMap.containsKey(key)) {
int count = constantMap.get(key);
count += 1;
constantMap.put(key, count);
} else {
constantMap.put(key,1);
}
}
public Map<String, Integer> getConstantMap() {
return constantMap;
}
public int getSpCount(){
return spCount;
}
public int getFilterCount() {
return filterCount;
}
}
}