IndexCostCalculator calculator,
String workspaceName,
ManagedIndex index,
final IndexDefinition defn ) {
ManagedLocalIndex localIndex = (ManagedLocalIndex)index;
IndexUsage planner = new IndexUsage(context, calculator, defn) {
@Override
protected boolean applies( FullTextSearch search ) {
// We don't support full text search criteria ...
return false;
}
@Override
protected boolean indexAppliesTo( Relike constraint ) {
// Relike can only work if the column types are all strings ...
for (IndexColumnDefinition columnDefn : defn) {
if (columnDefn.getColumnType() != PropertyType.STRING) return false;
}
return super.indexAppliesTo(constraint);
}
@Override
protected boolean indexAppliesTo( Comparison constraint ) {
if (QueryObjectModelConstants.JCR_OPERATOR_LIKE.equals(constraint.getOperator())) {
// Our indexes don't handle LIKE operations ...
return false;
}
return super.indexAppliesTo(constraint);
}
};
// Does this index apply to any of the ANDed constraints?
for (Constraint constraint : calculator.andedConstraints()) {
if (planner.indexAppliesTo(constraint)) {
logger().trace("Index '{0}' in '{1}' provider applies to query in workspace '{2}' with constraint: {3}",
defn.getName(), getName(), workspaceName, constraint);
// The index does apply to this constraint ...
long cardinality = localIndex.estimateCardinality(constraint, context.getVariables());
long total = localIndex.estimateTotalCount();
Float selectivity = null;
if (total >= 0L) {
double ratio = (double)cardinality / (double)total;
selectivity = cardinality <= total ? new Float(ratio) : MAX_SELECTIVITY;
}
calculator.addIndex(defn.getName(), workspaceName, getName(), Collections.singleton(constraint), Costs.LOCAL,
cardinality, selectivity);
}
}
// Does this index apply to any of the join conditions ...
for (JoinCondition joinCondition : calculator.joinConditions()) {
if (planner.indexAppliesTo(joinCondition)) {
logger().trace("Index '{0}' in '{1}' provider applies to query in workspace '{2}' with constraint: {3}",
defn.getName(), getName(), workspaceName, joinCondition);
// The index does apply to this constraint, but the number of values corresponds to the total number of values
// in the index (this is a JOIN CONDITON for which there is no literal values) ...
long total = localIndex.estimateTotalCount();