You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by jo...@apache.org on 2024/11/18 11:20:42 UTC
(jackrabbit-oak) 02/02: Reapply "OAK-11260 Speed up Lucene cost estimation (#1858)"
This is an automated email from the ASF dual-hosted git repository.
joscorbe pushed a commit to branch reapply-OAK1126-OAK11259
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
commit 808d4f44ec42e40df7f21a29b719d1ae3f13ac5b
Author: Jose Cordero <co...@adobe.com>
AuthorDate: Mon Nov 18 12:19:47 2024 +0100
Reapply "OAK-11260 Speed up Lucene cost estimation (#1858)"
This reverts commit 34fbbff6f186ace4c9cbf25f08939a70c7a91368.
---
.../apache/jackrabbit/oak/commons/Profiler.java | 3 +
.../oak/query/SQL2OptimiseQueryTest.java | 29 +++++++
.../index/lucene/LuceneIndexLookupUtil.java | 14 ++++
.../oak/jcr/query/ManyIndexesAndUnionPlanTest.java | 96 ++++++++++++++++++++++
.../oak/plugins/index/search/IndexDefinition.java | 2 +-
5 files changed, 143 insertions(+), 1 deletion(-)
diff --git a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/Profiler.java b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/Profiler.java
index b1161a9fb9..bd5044d5d1 100644
--- a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/Profiler.java
+++ b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/Profiler.java
@@ -389,6 +389,9 @@ public class Profiler implements Runnable {
boolean packageCounts = false;
for (int j = 0, i = 0; i < dump.length && j < depth; i++) {
String el = dump[i].toString();
+ if (el.startsWith("app//")) {
+ el = el.substring("app//".length());
+ }
if (!el.equals(last) && !startsWithAny(el, ignoreLines)) {
last = el;
buff.append("at ").append(el).append(LINE_SEPARATOR);
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2OptimiseQueryTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2OptimiseQueryTest.java
index c571cf01a4..f8685022ec 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2OptimiseQueryTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2OptimiseQueryTest.java
@@ -35,6 +35,8 @@ import static org.junit.Assert.assertTrue;
import java.text.ParseException;
import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.jcr.RepositoryException;
@@ -66,6 +68,33 @@ public class SQL2OptimiseQueryTest extends AbstractQueryTest {
}
};
+ @Test
+ public void limitUnionSize() throws ParseException {
+ String query = "SELECT * FROM [nt:base]\n"
+ + "WHERE (CONTAINS(*, '1') AND ([jcr:uuid] LIKE '2' OR [jcr:uuid] LIKE '3'))\n"
+ + " AND ((CONTAINS(*, '4') AND ([jcr:uuid] LIKE '5' OR [jcr:uuid] LIKE '6'))\n"
+ + " OR (CONTAINS(*, '0a') AND ([jcr:uuid] LIKE '0b' OR [jcr:uuid] LIKE '0c'))\n"
+ + " OR (CONTAINS(*, '1a') AND ([jcr:uuid] LIKE '1b' OR [jcr:uuid] LIKE '1c'))\n"
+ + " OR (CONTAINS(*, '2a') AND ([jcr:uuid] LIKE '2b' OR [jcr:uuid] LIKE '2c'))\n"
+ + " OR (CONTAINS(*, '3a') AND ([jcr:uuid] LIKE '3b' OR [jcr:uuid] LIKE '3c'))\n"
+ + " OR (CONTAINS(*, '4a') AND ([jcr:uuid] LIKE '4b' OR [jcr:uuid] LIKE '4c'))\n"
+ + " OR (CONTAINS(*, '5a') AND ([jcr:uuid] LIKE '5b' OR [jcr:uuid] LIKE '5c'))\n"
+ + " OR (CONTAINS(*, '6a') AND ([jcr:uuid] LIKE '6b' OR [jcr:uuid] LIKE '6c'))\n"
+ + " OR (CONTAINS(*, '7a') AND ([jcr:uuid] LIKE '7b' OR [jcr:uuid] LIKE '7c'))\n"
+ + " OR (CONTAINS(*, '8a') AND ([jcr:uuid] LIKE '8b' OR [jcr:uuid] LIKE '8c'))\n"
+ + " OR (CONTAINS(*, '9a') AND ([jcr:uuid] LIKE '9b' OR [jcr:uuid] LIKE '9c'))\n"
+ + " OR (CONTAINS(*, 'ea') AND ([jcr:uuid] LIKE 'eb' OR [jcr:uuid] LIKE 'ec')))\n"
+ + " AND ((CONTAINS(*, '10') AND ([jcr:uuid] LIKE '11' OR [jcr:uuid] LIKE '12'))\n"
+ + " OR (CONTAINS(*, '13') AND ([jcr:uuid] LIKE '14' OR [jcr:uuid] LIKE '15')))";
+ SQL2Parser parser = SQL2ParserTest.createTestSQL2Parser(
+ getMappings(), getNodeTypes(), qeSettings);
+ Query original;
+ original = parser.parse(query, false);
+ assertNotNull(original);
+ String alternative = original.buildAlternativeQuery().toString();
+ assertEquals(60825, alternative.length());
+ }
+
/**
* checks the {@code Query#optimise()} calls for the conversion from OR to UNION from a query
* POV; ensuring that it returns always the same, expected resultset.
diff --git a/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexLookupUtil.java b/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexLookupUtil.java
index 24c5fc9f5d..f0c2dd82a8 100644
--- a/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexLookupUtil.java
+++ b/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexLookupUtil.java
@@ -27,11 +27,17 @@ import org.apache.jackrabbit.oak.plugins.index.search.IndexFormatVersion;
import org.apache.jackrabbit.oak.plugins.index.search.IndexLookup;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.TYPE_LUCENE;
class LuceneIndexLookupUtil {
+
+ private static final Logger LOG = LoggerFactory.getLogger(LuceneIndexLookupUtil.class);
+
static final Predicate<NodeState> LUCENE_INDEX_DEFINITION_PREDICATE =
state -> TYPE_LUCENE.equals(state.getString(TYPE_PROPERTY_NAME));
@@ -45,6 +51,14 @@ class LuceneIndexLookupUtil {
public static String getOldFullTextIndexPath(NodeState root, Filter filter, IndexTracker tracker) {
Collection<String> indexPaths = getLuceneIndexLookup(root).collectIndexNodePaths(filter, false);
for (String path : indexPaths) {
+ NodeState node = NodeStateUtils.getNode(root, path);
+ if (IndexDefinition.determineIndexFormatVersion(node) != IndexFormatVersion.V1) {
+ // shortcut to avoid reading the index definition if not needed
+ continue;
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Old V1 lucene index found at {}", path);
+ }
IndexDefinition indexDefinition = tracker.getIndexDefinition(path);
if (indexDefinition != null && indexDefinition.isFullTextEnabled()
&& indexDefinition.getVersion() == IndexFormatVersion.V1) {
diff --git a/oak-lucene/src/test/java/org/apache/jackrabbit/oak/jcr/query/ManyIndexesAndUnionPlanTest.java b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/jcr/query/ManyIndexesAndUnionPlanTest.java
new file mode 100644
index 0000000000..4c6751bb46
--- /dev/null
+++ b/oak-lucene/src/test/java/org/apache/jackrabbit/oak/jcr/query/ManyIndexesAndUnionPlanTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+package org.apache.jackrabbit.oak.jcr.query;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+import javax.jcr.query.Row;
+import javax.jcr.query.RowIterator;
+
+import org.apache.jackrabbit.core.query.AbstractQueryTest;
+import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexFormatVersion;
+import org.junit.Test;
+
+public class ManyIndexesAndUnionPlanTest extends AbstractQueryTest {
+
+ @Test
+ public void testResultSize() throws Exception {
+ createIndexes();
+ createData();
+ doTestResultSize(10);
+ }
+
+ private void createIndexes() throws RepositoryException, InterruptedException {
+ Session session = superuser;
+ Node index = session.getRootNode().getNode("oak:index");
+ for (int i = 0; i < 10; i++) {
+ Node lucene = index.addNode("lucene" + i, "oak:QueryIndexDefinition");
+ lucene.setProperty("type", "lucene");
+ lucene.setProperty("async", "async");
+ lucene.setProperty(FulltextIndexConstants.COMPAT_MODE, IndexFormatVersion.V1.getVersion());
+ }
+ session.save();
+ }
+
+ private void createData() throws RepositoryException {
+ Session session = superuser;
+ for (int i = 0; i < 10; i++) {
+ Node n = testRootNode.addNode("node" + i);
+ n.setProperty("text", "Hello World");
+ }
+ session.save();
+ }
+
+ private void doTestResultSize(int expected) throws RepositoryException {
+ Session session = superuser;
+ QueryManager qm = session.getWorkspace().getQueryManager();
+
+ String xpath;
+ xpath = "/jcr:root//*[jcr:contains(@text, 'Hello World')]";
+
+ Query q;
+ long result;
+ NodeIterator it;
+ StringBuilder buff;
+
+ q = qm.createQuery(xpath, "xpath");
+ it = q.execute().getNodes();
+ result = it.getSize();
+ assertTrue("size: " + result + " expected around " + expected,
+ result > expected - 50 &&
+ result < expected + 50);
+ buff = new StringBuilder();
+ while (it.hasNext()) {
+ Node n = it.nextNode();
+ buff.append(n.getPath()).append('\n');
+ }
+ for (int j = 0; j < 1; j++) {
+ for (int i = 0; i < 1; i++) {
+ q = qm.createQuery("explain " + xpath, "xpath");
+ RowIterator rit = q.execute().getRows();
+ Row r = rit.nextRow();
+ assertTrue(r.toString().indexOf("luceneGlobal") >= 0);
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/IndexDefinition.java b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/IndexDefinition.java
index 3accb696d5..061733d819 100644
--- a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/IndexDefinition.java
+++ b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/IndexDefinition.java
@@ -1829,7 +1829,7 @@ public class IndexDefinition implements Aggregate.AggregateMapper {
nb.setProperty(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED, Type.NAME);
}
- protected static IndexFormatVersion determineIndexFormatVersion(NodeState defn) {
+ public static IndexFormatVersion determineIndexFormatVersion(NodeState defn) {
//Compat mode version if specified has highest priority
if (defn.hasProperty(COMPAT_MODE)) {
return versionFrom(defn.getProperty(COMPAT_MODE));