LuceneIndex implements AdvanceFulltextQueryIndex { @Override public List<IndexPlan> getPlans(Filter filter, List<OrderEntry> sortOrder, NodeState rootState) { FullTextExpression ft = filter.getFullTextConstraint(); if (ft == null) { return Collections.emptyList(); } String indexPath = LuceneIndexLookupUtil.getOldFullTextIndexPath(rootState, filter, tracker); if (indexPath == null) { return Collections.emptyList(); } Set<String> relPaths = getRelativePaths(ft); if (relPaths.size() > 1) { LOG.warn("More than one relative parent for query " + filter.getQueryStatement()); return Collections.emptyList(); } LuceneIndexNode node = tracker.acquireIndexNode(indexPath); try{ if (node != null){ IndexDefinition defn = node.getDefinition(); LuceneIndexStatistics stats = node.getIndexStatistics(); if (stats != null) { return Collections.singletonList(planBuilder(filter) .setEstimatedEntryCount(defn.getFulltextEntryCount(stats.numDocs())) .setCostPerExecution(defn.getCostPerExecution()) .setCostPerEntry(defn.getCostPerEntry()) .setDeprecated(defn.isDeprecated()) .setAttribute(ATTR_INDEX_PATH, indexPath) .setDeprecated(defn.isDeprecated()) .build()); } } return Collections.emptyList(); } finally { if (node != null){ node.release(); } } } LuceneIndex(IndexTracker tracker, NodeAggregator aggregator); @Override double getMinimumCost(); @Override String getIndexName(); @Override List<IndexPlan> getPlans(Filter filter, List<OrderEntry> sortOrder, NodeState rootState); @Override double getCost(Filter filter, NodeState root); @Override String getPlan(Filter filter, NodeState root); @Override String getPlanDescription(IndexPlan plan, NodeState root); @Override Cursor query(final Filter filter, final NodeState root); @Override Cursor query(final IndexPlan plan, NodeState rootState); @Override NodeAggregator getNodeAggregator(); static final String NATIVE_QUERY_FUNCTION; }
@Test public void indexNodeLockHandling() throws Exception{ tracker = new IndexTracker(); NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME); NodeBuilder nb = newLuceneIndexDefinitionV2(index, "lucene", of(TYPENAME_STRING)); nb.setProperty(FulltextIndexConstants.FULL_TEXT_ENABLED, false); nb.setProperty(createProperty(INCLUDE_PROPERTY_NAMES, of("foo"), STRINGS)); index = builder.child("test").child(INDEX_DEFINITIONS_NAME); NodeBuilder nb2 = newLuceneIndexDefinitionV2(index, "lucene", of(TYPENAME_STRING)); nb2.setProperty(FulltextIndexConstants.FULL_TEXT_ENABLED, false); nb2.setProperty(createProperty(INCLUDE_PROPERTY_NAMES, of("foo"), STRINGS)); NodeState before = builder.getNodeState(); builder.child("test").setProperty("foo", "fox is jumping"); NodeState after = builder.getNodeState(); NodeState indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY); tracker.update(indexed); QueryIndex.AdvancedQueryIndex queryIndex = new LucenePropertyIndex(tracker); FilterImpl filter = createFilter(NT_BASE); filter.restrictPath("/test", Filter.PathRestriction.EXACT); filter.restrictProperty("foo", Operator.EQUAL, PropertyValues.newString("bar")); builder = indexed.builder(); NodeBuilder dir = builder.child("oak:index").child("lucene").child(":data"); List<Blob> blobs = new ArrayList<>(); Blob b = dir.child("segments_1").getProperty(JCR_DATA).getValue(Type.BINARY, 0); FailingBlob fb = new FailingBlob(IOUtils.toByteArray(b.getNewStream())); blobs.add(fb); dir.child("segments_1").setProperty(JCR_DATA, blobs, BINARIES); indexed = builder.getNodeState(); tracker.update(indexed); List<IndexPlan> list = queryIndex.getPlans(filter, null, indexed); assertEquals("There must be only one plan", 1, list.size()); IndexPlan plan = list.get(0); assertEquals("Didn't get the expected plan", "/test/oak:index/lucene", plan.getPlanName()); }