use of org.apache.jackrabbit.oak.query.index.FilterImpl in project jackrabbit-oak by apache.
the class PropertyIndexTest method costMaxEstimation.
@Test
public void costMaxEstimation() throws Exception {
NodeState root = EmptyNodeState.EMPTY_NODE;
// Add index definition
NodeBuilder builder = root.builder();
createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "foo", true, false, ImmutableSet.of("foo"), null);
NodeState before = builder.getNodeState();
// 100 nodes in the index:
// with a single level /content cost is 121
// adding a second level /content/data cost is133
// 101 nodes in the index:
// with a single level /content cost is 121
// adding a second level /content/data cost is 133
// 100 nodes, 12 levels deep, cost is 345
// 101 nodes, 12 levels deep, cost is 345
// threshold for estimation (PropertyIndexLookup.MAX_COST) is at 100
int nodes = 101;
int levels = 12;
NodeBuilder data = builder;
for (int i = 0; i < levels; i++) {
data = data.child("l" + i);
}
for (int i = 0; i < nodes; i++) {
NodeBuilder c = data.child("c_" + i);
c.setProperty("foo", "azerty");
}
// add more nodes (to make traversal more expensive)
for (int i = 0; i < 10000; i++) {
data.child("cx_" + i);
}
NodeState after = builder.getNodeState();
NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
FilterImpl f = createFilter(indexed, NT_BASE);
PropertyIndexLookup lookup = new PropertyIndexLookup(indexed);
double cost = lookup.getCost(f, "foo", PropertyValues.newString("azerty"));
double traversal = new TraversingIndex().getCost(f, indexed);
assertTrue("Estimated cost for " + nodes + " nodes should not be higher than traversal (" + cost + " < " + traversal + ")", cost < traversal);
}
use of org.apache.jackrabbit.oak.query.index.FilterImpl in project jackrabbit-oak by apache.
the class ContentMirrorStoreStrategyTest method testIndexCountersUsageWithPathRestriction.
@Test
public void testIndexCountersUsageWithPathRestriction() {
final String subPathName = "sub-path";
final int filteredNodeFactor = 2;
final long repoTreeApproxNodeCount = 50000;
final long repoSubPathApproxNodeCount = repoTreeApproxNodeCount / filteredNodeFactor;
final FilterImpl filter = FilterImpl.newTestInstance();
filter.restrictPath("/" + subPathName, Filter.PathRestriction.ALL_CHILDREN);
final long approxNodeCount = 100;
final long approxKeyCount = 50;
final long entryCount = 60 * DEFAULT_RESOLUTION;
final long keyCount = 150;
final int maxTraversal = 200;
final String keyValue = KEY.iterator().next();
final String approxPropName = COUNT_PROPERTY_PREFIX + "gen_uuid";
IndexStoreStrategy store = new ContentMirrorStoreStrategy();
NodeBuilder rootBuilder = EMPTY_NODE.builder();
// setup tree for NodeCounter to work
rootBuilder.setProperty(COUNT_PROPERTY_NAME, repoTreeApproxNodeCount, Type.LONG);
NodeBuilder subPath = rootBuilder.child(subPathName);
subPath.setProperty(COUNT_PROPERTY_NAME, repoSubPathApproxNodeCount, Type.LONG);
NodeState root = rootBuilder.getNodeState();
NodeBuilder indexMeta = rootBuilder.child("propIndex");
NodeBuilder index = indexMeta.child(INDEX_CONTENT_NODE_NAME);
NodeBuilder key = index.child(keyValue);
// is-not-null query without entryCount
index.setProperty(approxPropName, approxNodeCount, Type.LONG);
assertInRange("Approximate count not used for is-not-null query", approxNodeCount, store.count(filter, root, indexMeta.getNodeState(), null, maxTraversal));
// prop=value query without entryCount
key.setProperty(approxPropName, approxKeyCount, Type.LONG);
assertInRange("Approximate count not used for key=value query", approxKeyCount, store.count(filter, root, indexMeta.getNodeState(), KEY, maxTraversal));
// is-not-null query with entryCount
indexMeta.setProperty(ENTRY_COUNT_PROPERTY_NAME, entryCount, Type.LONG);
assertInRange("Entry count not used even when present for is-not-null query", entryCount, filteredNodeFactor * store.count(filter, root, indexMeta.getNodeState(), null, maxTraversal));
// prop=value query with entryCount but without keyCount
Assert.assertTrue("Rough key count not considered for key=value query", entryCount > filteredNodeFactor * store.count(filter, root, indexMeta.getNodeState(), KEY, maxTraversal));
// prop=value query with entryCount and keyCount
indexMeta.setProperty(KEY_COUNT_PROPERTY_NAME, keyCount, Type.LONG);
Assert.assertTrue("Key count not considered for key=value query", entryCount > filteredNodeFactor * store.count(filter, root, indexMeta.getNodeState(), KEY, maxTraversal));
}
use of org.apache.jackrabbit.oak.query.index.FilterImpl in project jackrabbit-oak by apache.
the class ReferenceIndexTest method referenceHandlingWithMounts.
@Test
public void referenceHandlingWithMounts() throws Exception {
NodeState root = INITIAL_CONTENT;
NodeBuilder builder = root.builder();
NodeState before = builder.getNodeState();
builder.child("a").child("x").setProperty(createProperty("foo", "u1", Type.REFERENCE));
builder.child("b").setProperty(createProperty("foo", "u1", Type.REFERENCE));
builder.child("c").setProperty(createProperty("foo", "u1", Type.WEAKREFERENCE));
builder.child("d").setProperty(createProperty("foo", "u2", Type.WEAKREFERENCE));
builder.child("a").child("y").setProperty(createProperty("foo", "u1", Type.WEAKREFERENCE));
NodeState after = builder.getNodeState();
MountInfoProvider mip = Mounts.newBuilder().mount("foo", "/a").build();
EditorHook hook = new EditorHook(new IndexUpdateProvider(new ReferenceEditorProvider().with(mip)));
ReferenceIndex referenceIndex = new ReferenceIndex(mip);
NodeState indexed = hook.processCommit(before, after, CommitInfo.EMPTY);
FilterImpl f = createFilter(indexed, NT_BASE);
f.restrictProperty("*", Operator.EQUAL, newReference("u1"), PropertyType.REFERENCE);
// System.out.println(NodeStateUtils.toString(NodeStateUtils.getNode(indexed, "/oak:index/reference")));
assertFilter(f, referenceIndex, indexed, of("/a/x", "/b"));
FilterImpl f2 = createFilter(indexed, NT_BASE);
f2.restrictProperty("*", Operator.EQUAL, newReference("u1"), PropertyType.WEAKREFERENCE);
assertFilter(f2, referenceIndex, indexed, of("/c", "/a/y"));
}
use of org.apache.jackrabbit.oak.query.index.FilterImpl in project jackrabbit-oak by apache.
the class PropertyIndexTest method createFilter.
private static FilterImpl createFilter(NodeState root, String nodeTypeName) {
NodeTypeInfoProvider nodeTypes = new NodeStateNodeTypeInfoProvider(root);
NodeTypeInfo type = nodeTypes.getNodeTypeInfo(nodeTypeName);
SelectorImpl selector = new SelectorImpl(type, nodeTypeName);
return new FilterImpl(selector, "SELECT * FROM [" + nodeTypeName + "]", new QueryEngineSettings());
}
use of org.apache.jackrabbit.oak.query.index.FilterImpl in project jackrabbit-oak by apache.
the class PropertyIndexTest method testPathIncludeExclude.
@Test
public void testPathIncludeExclude() throws Exception {
NodeState root = INITIAL_CONTENT;
// Add index definition
NodeBuilder builder = root.builder();
NodeBuilder index = createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "foo", true, false, ImmutableSet.of("foo"), null);
index.setProperty(createProperty(PROP_INCLUDED_PATHS, of("/test/a"), Type.STRINGS));
index.setProperty(createProperty(PROP_EXCLUDED_PATHS, of("/test/a/b"), Type.STRINGS));
NodeState before = builder.getNodeState();
// Add some content and process it through the property index hook
builder.child("test").child("a").setProperty("foo", "abc");
builder.child("test").child("a").child("b").setProperty("foo", "abc");
NodeState after = builder.getNodeState();
NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
FilterImpl f = createFilter(indexed, NT_BASE);
f.restrictProperty("foo", Operator.EQUAL, PropertyValues.newString("abc"));
// Query the index
PropertyIndexLookup lookup = new PropertyIndexLookup(indexed);
assertEquals(ImmutableSet.of("test/a"), find(lookup, "foo", "abc", f));
//no path restriction, opt out
PropertyIndexPlan plan = new PropertyIndexPlan("plan", root, index.getNodeState(), f);
assertTrue(Double.POSITIVE_INFINITY == plan.getCost());
//path restriction is not an ancestor of excluded path, index may be used
f.setPath("/test/a/x");
plan = new PropertyIndexPlan("plan", root, index.getNodeState(), f);
assertTrue(Double.POSITIVE_INFINITY != plan.getCost());
//path restriction is an ancestor of excluded path but no included path, opt out
f.setPath("/test/a/b");
plan = new PropertyIndexPlan("plan", root, index.getNodeState(), f);
assertTrue(Double.POSITIVE_INFINITY == plan.getCost());
//path restriction is an ancestor of excluded path, opt out
f.setPath("/test/a");
plan = new PropertyIndexPlan("plan", root, index.getNodeState(), f);
assertTrue(Double.POSITIVE_INFINITY == plan.getCost());
}
Aggregations