Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ChildAxisQuery.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ChildAxisQuery.java (revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ChildAxisQuery.java (revision )
@@ -32,6 +32,8 @@
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Scorer;
@@ -92,7 +94,7 @@
/**
* The index format version.
- */
+ */
private final IndexFormatVersion version;
/**
@@ -114,11 +116,11 @@
* Creates a new ChildAxisQuery
based on a context
* query.
*
- * @param itemMgr the item state manager.
+ * @param itemMgr the item state manager.
- * @param context the context for this query.
+ * @param context the context for this query.
- * @param nameTest a name test or null
if any child node is
+ * @param nameTest a name test or null
if any child node is
- * selected.
+ * selected.
- * @param version the index format version.
+ * @param version the index format version.
* @param nsMappings the internal namespace mappings.
*/
ChildAxisQuery(ItemStateManager itemMgr,
@@ -133,14 +135,14 @@
* Creates a new ChildAxisQuery
based on a context
* query.
*
- * @param itemMgr the item state manager.
+ * @param itemMgr the item state manager.
- * @param context the context for this query.
+ * @param context the context for this query.
- * @param nameTest a name test or null
if any child node is
+ * @param nameTest a name test or null
if any child node is
- * selected.
+ * selected.
- * @param position the context position of the child node to select. If
+ * @param position the context position of the child node to select. If
- * position
is {@link LocationStepQueryNode#NONE}, the context
+ * position
is {@link LocationStepQueryNode#NONE}, the context
- * position of the child node is not checked.
+ * position of the child node is not checked.
- * @param version the index format version.
+ * @param version the index format version.
* @param nsMapping the internal namespace mappings.
*/
ChildAxisQuery(ItemStateManager itemMgr,
@@ -166,7 +168,7 @@
/**
* @return true
if this child axis query matches any child
- * node; false
otherwise.
+ * node; false
otherwise.
*/
boolean matchesAnyChildNode() {
return nameTest == null && position == LocationStepQueryNode.NONE;
@@ -181,7 +183,7 @@
/**
* @return the position check or {@link LocationStepQueryNode#NONE} is none
- * was specified.
+ * was specified.
*/
int getPosition() {
return position;
@@ -212,7 +214,7 @@
// only try to compact if no position is specified
if (position == LocationStepQueryNode.NONE) {
if (cQuery instanceof DescendantSelfAxisQuery) {
- DescendantSelfAxisQuery dsaq = (DescendantSelfAxisQuery) cQuery;
+ DescendantSelfAxisQuery dsaq = (DescendantSelfAxisQuery)cQuery;
if (dsaq.subQueryMatchesAll()) {
Query sub;
if (nameTest == null) {
@@ -334,7 +336,7 @@
nameTestScorer = new NameQuery(nameTest, version, nsMappings).weight(searcher).scorer(reader, scoreDocsInOrder, false);
}
return new ChildAxisScorer(searcher.getSimilarity(),
- reader, (HierarchyResolver) reader);
+ reader, searcher, (HierarchyResolver)reader);
}
/**
@@ -372,20 +374,36 @@
*/
private Hits hits;
+ private DocIdSet filter;
+
+ private boolean filterIteratorExhausted;
+
+ private DocIdSetIterator filterIterator;
+
/**
* Creates a new ChildAxisScorer
.
*
* @param similarity the Similarity
instance to use.
* @param reader for index access.
+ * @param searcher
* @param hResolver the hierarchy resolver of reader
.
*/
protected ChildAxisScorer(Similarity similarity,
IndexReader reader,
+ final Searcher searcher,
HierarchyResolver hResolver) {
super(similarity);
this.reader = reader;
this.hResolver = hResolver;
+ if (searcher instanceof JackrabbitIndexSearcher && ((JackrabbitIndexSearcher)searcher).getFilter() != null) {
+ try {
+ // we need two
+ filter = ((JackrabbitIndexSearcher)searcher).getFilter().getDocIdSet(reader);
+ } catch (IOException e) {
+ log.warn("IOException while getting filter : ", e.toString());
- }
+ }
+ }
+ }
@Override
public int nextDoc() throws IOException {
@@ -394,9 +412,10 @@
}
calculateChildren();
+
do {
nextDoc = hits.next();
- } while (nextDoc > -1 && !indexIsValid(nextDoc));
+ } while (nextDoc > -1 && (isFiltered(nextDoc, filterIterator) || !indexIsValid(nextDoc)));
if (nextDoc < 0) {
nextDoc = NO_MORE_DOCS;
@@ -419,7 +438,7 @@
if (nextDoc == NO_MORE_DOCS) {
return nextDoc;
}
-
+
// optimize in the case of an advance to finish.
// see https://issues.apache.org/jira/browse/JCR-3091
if (target == NO_MORE_DOCS) {
@@ -429,12 +448,13 @@
}
calculateChildren();
+
nextDoc = hits.skipTo(target);
if (nextDoc < 0) {
nextDoc = NO_MORE_DOCS;
}
- while (nextDoc != NO_MORE_DOCS && !indexIsValid(nextDoc)) {
+ while (nextDoc != NO_MORE_DOCS && (isFiltered(nextDoc, filterIterator) || !indexIsValid(nextDoc))) {
nextDoc();
}
return nextDoc;
@@ -442,7 +462,7 @@
private void calculateChildren() throws IOException {
if (hits == null) {
-
+ resetOrInitFilter();
final ChildrenCalculator[] calc = new ChildrenCalculator[1];
if (nameTestScorer == null) {
// always use simple in that case
@@ -450,6 +470,9 @@
contextScorer.score(new AbstractHitCollector() {
@Override
protected void collect(int doc, float score) {
+ if (isFiltered(doc, filterIterator)) {
+ return;
+ }
calc[0].collectContextHit(doc);
}
});
@@ -462,6 +485,9 @@
@Override
protected void collect(int doc, float score) {
+ if (isFiltered(doc, filterIterator)) {
+ return;
+ }
calc[0].collectContextHit(doc);
if (docIds != null) {
docIds.add(doc);
@@ -482,15 +508,53 @@
hits = calc[0].getHits();
}
+ // reset the iterator since it only advances and it is used to check the 'self' docs now.
+ // next the children will be checked that require with a clean fresh iterator
+ resetOrInitFilter();
}
+ private void resetOrInitFilter() throws IOException {
+ filterIteratorExhausted = false;
+ if (filter == null) {
+ filterIterator = null;
+ } else {
+ filterIterator = filter.iterator();
+ }
+ }
+
+ private boolean isFiltered(final int doc, final DocIdSetIterator filterIterator) {
+ if (filterIterator == null) {
+ return false;
+ }
+
+ if (filterIteratorExhausted) {
+ return true;
+ }
+
+ try {
+ final int advance = filterIterator.advance(doc);
+ if (NO_MORE_DOCS == advance) {
+ filterIteratorExhausted = true;
+ return true;
+ }
+ if (advance != doc) {
+ // doc is not readable by filter : Don't return the possibly readable parent!
+ return true;
+ }
+ } catch (IOException e) {
+ log.warn("Exception while use filter : {}", e.toString());
+ return true;
+ }
+ return false;
+ }
+
private boolean indexIsValid(int i) throws IOException {
if (position != LocationStepQueryNode.NONE) {
Document node = reader.document(i, FieldSelectors.UUID_AND_PARENT);
NodeId parentId = NodeId.valueOf(node.get(FieldNames.PARENT));
NodeId id = NodeId.valueOf(node.get(FieldNames.UUID));
try {
- NodeState state = (NodeState) itemMgr.getItemState(parentId);
+ NodeState state = (NodeState)itemMgr.getItemState(parentId);
if (nameTest == null) {
// only select this node if it is the child at
// specified position
@@ -547,6 +611,7 @@
}
return true;
}
+
}
/**
@@ -568,7 +633,7 @@
* Creates a new children calculator with the given index reader and
* hierarchy resolver.
*
- * @param reader the current index reader.
+ * @param reader the current index reader.
* @param hResolver the current hierarchy resolver.
*/
public ChildrenCalculator(IndexReader reader,
@@ -604,7 +669,7 @@
/**
* Creates a new simple children calculator.
*
- * @param reader the current index reader.
+ * @param reader the current index reader.
* @param hResolver the current hierarchy resolver.
*/
public SimpleChildrenCalculator(IndexReader reader,
@@ -636,7 +701,7 @@
NodeId id = new NodeId(uuid);
try {
long time = System.currentTimeMillis();
- NodeState state = (NodeState) itemMgr.getItemState(id);
+ NodeState state = (NodeState)itemMgr.getItemState(id);
time = System.currentTimeMillis() - time;
log.debug("got NodeState with id {} in {} ms.", id, time);
List entries;
@@ -682,7 +747,7 @@
/**
* Creates a new hierarchy resolving children calculator.
*
- * @param reader the current index reader.
+ * @param reader the current index reader.
* @param hResolver the current hierarchy resolver.
*/
public HierarchyResolvingChildrenCalculator(IndexReader reader,
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ParentAxisQuery.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ParentAxisQuery.java (revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ParentAxisQuery.java (revision )
@@ -22,12 +22,15 @@
import org.apache.jackrabbit.spi.Name;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
+import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.Similarity;
import org.apache.lucene.search.Weight;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.BitSet;
@@ -41,6 +44,8 @@
@SuppressWarnings("serial")
class ParentAxisQuery extends Query {
+ private static final Logger log = LoggerFactory.getLogger(ParentAxisQuery.class);
+
/**
* The context query
*/
@@ -71,14 +76,14 @@
* Creates a new ParentAxisQuery
based on a
* context
query.
*
- * @param context the context for this query.
+ * @param context the context for this query.
- * @param nameTest a name test or null
if any parent node is
+ * @param nameTest a name test or null
if any parent node is
- * selected.
+ * selected.
- * @param version the index format version.
+ * @param version the index format version.
* @param nsMappings the internal namespace mappings.
*/
ParentAxisQuery(Query context, Name nameTest,
- IndexFormatVersion version, NamespaceMappings nsMappings) {
+ IndexFormatVersion version, NamespaceMappings nsMappings) {
this.contextQuery = context;
this.nameTest = nameTest;
this.version = version;
@@ -189,9 +194,9 @@
* @throws IOException if an error occurs while reading from the index.
*/
public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder,
- boolean topScorer) throws IOException {
+ boolean topScorer) throws IOException {
contextScorer = contextQuery.weight(searcher).scorer(reader, scoreDocsInOrder, false);
- HierarchyResolver resolver = (HierarchyResolver) reader;
+ HierarchyResolver resolver = (HierarchyResolver)reader;
return new ParentAxisScorer(searcher.getSimilarity(),
reader, searcher, resolver);
}
@@ -251,6 +256,10 @@
*/
private Float firstScore;
+ private DocIdSetIterator filterIterator;
+
+ private boolean filterIteratorExhausted;
+
/**
* Creates a new ParentAxisScorer
.
*
@@ -267,7 +276,14 @@
this.reader = reader;
this.searcher = searcher;
this.hResolver = resolver;
+ if (searcher instanceof JackrabbitIndexSearcher && ((JackrabbitIndexSearcher)searcher).getFilter() != null) {
+ try {
+ filterIterator = ((JackrabbitIndexSearcher)searcher).getFilter().getDocIdSet(reader).iterator();
+ } catch (IOException e) {
+ log.warn("IOException while getting filter : ", e.toString());
- }
+ }
+ }
+ }
@Override
public int nextDoc() throws IOException {
@@ -327,6 +343,26 @@
@Override
protected void collect(int doc, float score) {
+ if (filterIterator != null) {
+ if (filterIteratorExhausted) {
+ // filter does not have any more allowed doc
+ return;
+ }
+ try {
+ final int advance = filterIterator.advance(doc);
+ if (advance == NO_MORE_DOCS) {
+ // filter exhausted: We should not invoke #advance any more
+ filterIteratorExhausted = true;
+ }
+ if (advance != doc) {
+ // doc is not readable by filter : Don't return the possibly readable parent!
+ return;
+ }
+ } catch (IOException e) {
+ log.warn("Exception while use filter : {}", e.toString());
+ return;
+ }
+ }
try {
docs = hResolver.getParents(doc, docs);
if (docs.length == 1) {
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java (revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java (revision )
@@ -24,6 +24,7 @@
import org.apache.jackrabbit.spi.Name;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
+import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
@@ -50,6 +51,7 @@
* The item state manager of the workspace.
*/
private final ItemStateManager ism;
+ private Filter filter;
/**
* Creates a new jackrabbit index searcher.
@@ -61,10 +63,18 @@
public JackrabbitIndexSearcher(SessionImpl s,
IndexReader r,
ItemStateManager ism) {
+ this(s,r, ism, null);
+ }
+
+ public JackrabbitIndexSearcher(SessionImpl s,
+ IndexReader r,
+ ItemStateManager ism,
+ Filter f) {
super(r);
this.session = s;
this.reader = r;
this.ism = ism;
+ this.filter = f;
}
/**
@@ -151,5 +161,12 @@
*/
public ItemStateManager getItemStateManager() {
return ism;
+ }
+
+ /**
+ * @return the {@link Filter} used for this searcher or {@code null} if not present
+ */
+ public Filter getFilter() {
+ return filter;
}
}