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 ch...@apache.org on 2014/10/13 07:09:58 UTC
svn commit: r1631284 - in /jackrabbit/oak/trunk/oak-lucene/src:
main/java/org/apache/jackrabbit/oak/plugins/index/lucene/
main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/
test/java/org/apache/jackrabbit/oak/plugins/index/lucene/
Author: chetanm
Date: Mon Oct 13 05:09:57 2014
New Revision: 1631284
URL: http://svn.apache.org/r1631284
Log:
OAK-2005 - Use separate Lucene index for performing property related queries
- Modifying logic to support multiple Lucene index definitions. For compatibility purpose the first full text enabled Lucene index would be used
- Introduced IndexDefinition class to encapsulate index definitions node
Added:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java (with props)
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexLookup.java (with props)
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexHelper.java
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LowCostLuceneIndexProvider.java
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
Added: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java?rev=1631284&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java (added)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java Mon Oct 13 05:09:57 2014
@@ -0,0 +1,115 @@
+/*
+ * 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.plugins.index.lucene;
+
+import java.util.Collections;
+import java.util.Set;
+
+import javax.jcr.PropertyType;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.EXCLUDE_PROPERTY_NAMES;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.FULL_TEXT_ENABLED;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INCLUDE_PROPERTY_NAMES;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INCLUDE_PROPERTY_TYPES;
+
+public class IndexDefinition {
+ private static final Logger log = LoggerFactory.getLogger(IndexDefinition.class);
+ private final int propertyTypes;
+
+ private final Set<String> excludes;
+
+ private final Set<String> includes;
+
+ private final boolean fullTextEnabled;
+
+ private final NodeBuilder definition;
+
+ public IndexDefinition(NodeBuilder defn) {
+ this.definition = defn;
+ PropertyState pst = defn.getProperty(INCLUDE_PROPERTY_TYPES);
+ if (pst != null) {
+ int types = 0;
+ for (String inc : pst.getValue(Type.STRINGS)) {
+ try {
+ types |= 1 << PropertyType.valueFromName(inc);
+ } catch (IllegalArgumentException e) {
+ log.warn("Unknown property type: " + inc);
+ }
+ }
+ this.propertyTypes = types;
+ } else {
+ this.propertyTypes = -1;
+ }
+
+ this.excludes = toLowerCase(getMultiProperty(defn, EXCLUDE_PROPERTY_NAMES));
+ this.includes = getMultiProperty(defn, INCLUDE_PROPERTY_NAMES);
+ this.fullTextEnabled = getOptionalValue(defn, FULL_TEXT_ENABLED, true);
+ }
+
+ boolean includeProperty(String name) {
+ if(!includes.isEmpty()){
+ return includes.contains(name);
+ }
+ return !excludes.contains(name.toLowerCase());
+ }
+
+ boolean includePropertyType(int type){
+ if(propertyTypes < 0){
+ return false;
+ }
+ return (propertyTypes & (1 << type)) != 0;
+ }
+
+ public NodeBuilder getDefinition() {
+ return definition;
+ }
+
+ public boolean isFullTextEnabled() {
+ return fullTextEnabled;
+ }
+
+ //~------------------------------------------< Internal >
+
+ private static boolean getOptionalValue(NodeBuilder definition, String propName, boolean defaultVal){
+ PropertyState ps = definition.getProperty(propName);
+ return ps == null ? defaultVal : ps.getValue(Type.BOOLEAN);
+ }
+
+ private static Set<String> getMultiProperty(NodeBuilder definition, String propName){
+ PropertyState pse = definition.getProperty(propName);
+ return pse != null ? ImmutableSet.copyOf(pse.getValue(Type.STRINGS)) : Collections.<String>emptySet();
+ }
+
+ private static Set<String> toLowerCase(Set<String> values){
+ Set<String> result = Sets.newHashSet();
+ for(String val : values){
+ result.add(val.toLowerCase());
+ }
+ return Collections.unmodifiableSet(result);
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java?rev=1631284&r1=1631283&r2=1631284&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java Mon Oct 13 05:09:57 2014
@@ -68,7 +68,7 @@ class IndexNode {
private final String name;
- private final NodeState definition;
+ private final IndexDefinition definition;
private final Directory directory;
@@ -83,7 +83,7 @@ class IndexNode {
IndexNode(String name, NodeState definition, Directory directory)
throws IOException {
this.name = name;
- this.definition = definition;
+ this.definition = new IndexDefinition(new ReadOnlyBuilder(definition));
this.directory = directory;
this.reader = DirectoryReader.open(directory);
this.searcher = new IndexSearcher(reader);
@@ -93,7 +93,7 @@ class IndexNode {
return name;
}
- NodeState getDefinition() {
+ IndexDefinition getDefinition() {
return definition;
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java?rev=1631284&r1=1631283&r2=1631284&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java Mon Oct 13 05:09:57 2014
@@ -20,15 +20,13 @@ import static com.google.common.base.Pre
import static com.google.common.base.Predicates.in;
import static com.google.common.base.Predicates.not;
import static com.google.common.base.Predicates.notNull;
-import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.newArrayListWithCapacity;
import static com.google.common.collect.Maps.filterKeys;
import static com.google.common.collect.Maps.filterValues;
import static com.google.common.collect.Maps.newHashMap;
import static java.util.Collections.emptyMap;
-import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
-import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.TYPE_LUCENE;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper.isLuceneIndexNode;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
import java.io.IOException;
@@ -42,7 +40,6 @@ import org.apache.jackrabbit.oak.spi.com
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.commit.EditorDiff;
import org.apache.jackrabbit.oak.spi.commit.SubtreeEditor;
-import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -82,10 +79,6 @@ class IndexTracker {
final String path = entry.getKey();
final String name = entry.getValue().getName();
- List<String> elements = newArrayList();
- Iterables.addAll(elements, PathUtils.elements(path));
- elements.add(INDEX_DEFINITIONS_NAME);
- elements.add(name);
editors.add(new SubtreeEditor(new DefaultEditor() {
@Override
public void leave(NodeState before, NodeState after) {
@@ -97,7 +90,7 @@ class IndexTracker {
log.error("Failed to open Lucene index at " + path, e);
}
}
- }, elements.toArray(new String[elements.size()])));
+ }, Iterables.toArray(PathUtils.elements(path), String.class)));
}
EditorDiff.process(CompositeEditor.compose(editors), this.root, root);
@@ -145,24 +138,23 @@ class IndexTracker {
NodeState node = root;
for (String name : PathUtils.elements(path)) {
- node = root.getChildNode(name);
+ node = node.getChildNode(name);
}
- node = node.getChildNode(INDEX_DEFINITIONS_NAME);
+ final String indexName = PathUtils.getName(path);
try {
- for (ChildNodeEntry child : node.getChildNodeEntries()) {
- node = child.getNodeState();
- if (TYPE_LUCENE.equals(node.getString(TYPE_PROPERTY_NAME))) {
- index = IndexNode.open(child.getName(), node);
- if (index != null) {
- checkState(index.acquire());
- indices = ImmutableMap.<String, IndexNode>builder()
- .putAll(indices)
- .put(path, index)
- .build();
- return index;
- }
+ if (isLuceneIndexNode(node)) {
+ index = IndexNode.open(indexName, node);
+ if (index != null) {
+ checkState(index.acquire());
+ indices = ImmutableMap.<String, IndexNode>builder()
+ .putAll(indices)
+ .put(path, index)
+ .build();
+ return index;
}
+ } else if (node.exists()) {
+ log.warn("Cannot open Lucene Index at path {} as the index is not of type {}", path, TYPE_LUCENE);
}
} catch (IOException e) {
log.error("Could not access the Lucene index at " + path, e);
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java?rev=1631284&r1=1631283&r2=1631284&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java Mon Oct 13 05:09:57 2014
@@ -26,8 +26,6 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldNames.PATH;
-import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.EXCLUDE_PROPERTY_NAMES;
-import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INCLUDE_PROPERTY_TYPES;
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.VERSION;
import static org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newFulltextTerm;
import static org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newPathTerm;
@@ -50,7 +48,6 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
-import javax.jcr.PropertyType;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.Queues;
@@ -152,13 +149,19 @@ public class LuceneIndex implements Adva
public static final String NATIVE_QUERY_FUNCTION = "native*lucene";
/**
+ * IndexPaln Attribute name which refers to the path of Lucene index to be used
+ * to perform query
+ */
+ static final String ATTR_INDEX_PATH = "oak.lucene.indexPath";
+
+ /**
* Batch size for fetching results from Lucene queries.
*/
static final int LUCENE_QUERY_BATCH_SIZE = 50;
-
+
static final boolean USE_PATH_RESTRICTION = Boolean.getBoolean("oak.luceneUsePath");
- private final IndexTracker tracker;
+ protected final IndexTracker tracker;
private final Analyzer analyzer;
@@ -186,37 +189,35 @@ public class LuceneIndex implements Adva
return Collections.emptyList();
}
- IndexNode index = tracker.acquireIndexNode("/");
- if (index == null) { // unusable index
+ String indexPath = new LuceneIndexLookup(rootState).getFullTextIndexPath(filter, tracker);
+ if (indexPath == null) { // unusable index
return Collections.emptyList();
}
- try {
- Set<String> relPaths = getRelativePaths(ft);
- if (relPaths.size() > 1) {
- LOG.warn("More than one relative parent for query " + filter.getQueryStatement());
- // there are multiple "parents", as in
- // "contains(a/x, 'hello') and contains(b/x, 'world')"
- return Collections.emptyList();
- }
- String parent = relPaths.iterator().next();
-
- // no relative properties
- double cost = 10;
- if (!parent.isEmpty()) {
- // all relative properties have the same "parent", as in
- // "contains(a/x, 'hello') and contains(a/y, 'world')" or
- // "contains(a/x, 'hello') or contains(a/*, 'world')"
- // TODO: proper cost calculation
- // we assume this will cause more read operations,
- // as we need to read the node and then the parent
- cost = 15;
- }
- return Collections.singletonList(planBuilder(filter)
- .setCostPerExecution(cost)
- .build());
- } finally {
- index.release();
+ Set<String> relPaths = getRelativePaths(ft);
+ if (relPaths.size() > 1) {
+ LOG.warn("More than one relative parent for query " + filter.getQueryStatement());
+ // there are multiple "parents", as in
+ // "contains(a/x, 'hello') and contains(b/x, 'world')"
+ return Collections.emptyList();
}
+ String parent = relPaths.iterator().next();
+
+ // no relative properties
+ double cost = 10;
+ if (!parent.isEmpty()) {
+ // all relative properties have the same "parent", as in
+ // "contains(a/x, 'hello') and contains(a/y, 'world')" or
+ // "contains(a/x, 'hello') or contains(a/*, 'world')"
+ // TODO: proper cost calculation
+ // we assume this will cause more read operations,
+ // as we need to read the node and then the parent
+ cost = 15;
+ }
+ return Collections.singletonList(planBuilder(filter)
+ .setCostPerExecution(cost)
+ .setAttribute(ATTR_INDEX_PATH, indexPath)
+ .build());
+
}
@Override
@@ -232,7 +233,7 @@ public class LuceneIndex implements Adva
@Override
public String getPlanDescription(IndexPlan plan, NodeState root) {
Filter filter = plan.getFilter();
- IndexNode index = tracker.acquireIndexNode("/");
+ IndexNode index = tracker.acquireIndexNode((String) plan.getAttribute(ATTR_INDEX_PATH));
checkState(index != null, "The Lucene index is not available");
try {
FullTextExpression ft = filter.getFullTextConstraint();
@@ -260,7 +261,7 @@ public class LuceneIndex implements Adva
}
@Override
- public Cursor query(IndexPlan plan, NodeState rootState) {
+ public Cursor query(final IndexPlan plan, NodeState rootState) {
final Filter filter = plan.getFilter();
FullTextExpression ft = filter.getFullTextConstraint();
Set<String> relPaths = getRelativePaths(ft);
@@ -325,7 +326,7 @@ public class LuceneIndex implements Adva
private boolean loadDocs() {
ScoreDoc lastDocToRecord = null;
- IndexNode indexNode = tracker.acquireIndexNode("/");
+ IndexNode indexNode = tracker.acquireIndexNode((String) plan.getAttribute(ATTR_INDEX_PATH));
checkState(indexNode != null);
try {
IndexSearcher searcher = indexNode.getSearcher();
@@ -437,7 +438,7 @@ public class LuceneIndex implements Adva
* @return the Lucene query
*/
private static Query getQuery(Filter filter, IndexReader reader,
- boolean nonFullTextConstraints, Analyzer analyzer, NodeState indexDefinition) {
+ boolean nonFullTextConstraints, Analyzer analyzer, IndexDefinition indexDefinition) {
List<Query> qs = new ArrayList<Query>();
FullTextExpression ft = filter.getFullTextConstraint();
if (ft == null) {
@@ -485,7 +486,7 @@ public class LuceneIndex implements Adva
}
private static void addNonFullTextConstraints(List<Query> qs,
- Filter filter, IndexReader reader, Analyzer analyzer, NodeState indexDefinition) {
+ Filter filter, IndexReader reader, Analyzer analyzer, IndexDefinition indexDefinition) {
if (!filter.matchesAllTypes()) {
addNodeTypeConstraints(qs, filter);
}
@@ -629,7 +630,7 @@ public class LuceneIndex implements Adva
}
private static boolean isExcludedProperty(PropertyRestriction pr,
- NodeState definition) {
+ IndexDefinition definition) {
String name = pr.propertyName;
if (name.contains("/")) {
// lucene cannot handle child-level property restrictions
@@ -637,10 +638,8 @@ public class LuceneIndex implements Adva
}
// check name
- for (String e : definition.getStrings(EXCLUDE_PROPERTY_NAMES)) {
- if (e.equalsIgnoreCase(name)) {
- return true;
- }
+ if(!definition.includeProperty(name)){
+ return true;
}
// check type
@@ -653,13 +652,7 @@ public class LuceneIndex implements Adva
type = pr.list.get(0).getType().tag();
}
if (type != null) {
- boolean isIn = false;
- for (String e : definition.getStrings(INCLUDE_PROPERTY_TYPES)) {
- if (PropertyType.valueFromName(e) == type) {
- isIn = true;
- }
- }
- if (!isIn) {
+ if (!definition.includePropertyType(type)) {
return true;
}
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java?rev=1631284&r1=1631283&r2=1631284&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java Mon Oct 13 05:09:57 2014
@@ -54,4 +54,16 @@ public interface LuceneIndexConstants {
*/
String EXPERIMENTAL_STORAGE = "oak.experimental.storage";
+ /**
+ * Determines if full text indexing is enabled for this index definition.
+ * Default is true
+ */
+ String FULL_TEXT_ENABLED = "fulltextEnabled";
+
+ /**
+ * Only include properties with name in this set. If this property is defined
+ * then {@code excludePropertyNames} would be ignored
+ */
+ String INCLUDE_PROPERTY_NAMES = "includePropertyNames";
+
}
Added: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexLookup.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexLookup.java?rev=1631284&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexLookup.java (added)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexLookup.java Mon Oct 13 05:09:57 2014
@@ -0,0 +1,83 @@
+/*
+ * 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.plugins.index.lucene;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper.isLuceneIndexNode;
+
+public class LuceneIndexLookup {
+ private final NodeState root;
+
+ public LuceneIndexLookup(NodeState root) {
+ this.root = root;
+ }
+
+ /**
+ * Returns the path of the first Lucene index node which supports
+ * fulltext search
+ */
+ public String getFullTextIndexPath(Filter filter, IndexTracker tracker) {
+ List<String> indexPaths = collectIndexNodePaths(filter);
+ IndexNode indexNode = null;
+ for (String path : indexPaths) {
+ try {
+ indexNode = tracker.acquireIndexNode(path);
+ if (indexNode != null
+ && indexNode.getDefinition().isFullTextEnabled()) {
+ return path;
+ }
+ } finally {
+ if (indexNode != null) {
+ indexNode.release();
+ }
+ }
+ }
+ return null;
+ }
+
+ private List<String> collectIndexNodePaths(Filter filter){
+ List<String> paths = Lists.newArrayList();
+ collectIndexNodePaths(filter.getPath(), paths);
+ return paths;
+ }
+
+ private void collectIndexNodePaths(String filterPath, List<String> paths) {
+ //TODO Add support for looking index nodes from non root paths
+ NodeState state = root.getChildNode(INDEX_DEFINITIONS_NAME);
+ for (ChildNodeEntry entry : state.getChildNodeEntries()) {
+ if (isLuceneIndexNode(entry.getNodeState())) {
+ paths.add(createIndexNodePath(entry.getName()));
+ }
+ }
+ }
+
+ private String createIndexNodePath(String name){
+ //TODO getPath would lead to duplicate path constru
+ return PathUtils.concat("/", INDEX_DEFINITIONS_NAME, name);
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexLookup.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexHelper.java?rev=1631284&r1=1631283&r2=1631284&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexHelper.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexHelper.java Mon Oct 13 05:09:57 2014
@@ -45,6 +45,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
public class LuceneIndexHelper {
@@ -151,4 +152,8 @@ public class LuceneIndexHelper {
public static boolean skipTokenization(String name) {
return NOT_TOKENIZED.contains(name);
}
+
+ public static boolean isLuceneIndexNode(NodeState node){
+ return TYPE_LUCENE.equals(node.getString(TYPE_PROPERTY_NAME));
+ }
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LowCostLuceneIndexProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LowCostLuceneIndexProvider.java?rev=1631284&r1=1631283&r2=1631284&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LowCostLuceneIndexProvider.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LowCostLuceneIndexProvider.java Mon Oct 13 05:09:57 2014
@@ -44,8 +44,10 @@ public class LowCostLuceneIndexProvider
@Override
public List<IndexPlan> getPlans(Filter filter, List<OrderEntry> sortOrder, NodeState rootState) {
+ String indexPath = new LuceneIndexLookup(rootState).getFullTextIndexPath(filter, tracker);
return Collections.singletonList(planBuilder(filter)
.setCostPerExecution(1e-3)
+ .setAttribute(ATTR_INDEX_PATH, indexPath)
.build());
}
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java?rev=1631284&r1=1631283&r2=1631284&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java Mon Oct 13 05:09:57 2014
@@ -289,7 +289,10 @@ public class LuceneIndexTest {
}
private IndexPlan createPlan(Filter filter){
- return new IndexPlan.Builder().setFilter(filter).build();
+ return new IndexPlan.Builder()
+ .setFilter(filter)
+ .setAttribute(LuceneIndex.ATTR_INDEX_PATH, "/oak:index/lucene")
+ .build();
}
}