Index: src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractIndex.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractIndex.java (revision 548680)
+++ src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractIndex.java (working copy)
@@ -32,6 +32,8 @@
import java.io.StringReader;
import java.util.BitSet;
import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
/**
* Implements common functionality for a lucene index.
@@ -90,6 +92,9 @@
/** The shared IndexReader for all read-only IndexReaders */
private SharedIndexReader sharedReader;
+ /** Caches all read-only IndexReaders */
+ private Map readOnlyReaders = new HashMap();
+
/**
* The indexing queue.
*/
@@ -205,7 +210,12 @@
CachingIndexReader cr = new CachingIndexReader(IndexReader.open(getDirectory()), cache);
sharedReader = new SharedIndexReader(cr);
}
- return new ReadOnlyIndexReader(sharedReader, deleted);
+ ReadOnlyIndexReader cachedReadOnlyIndexReader = (ReadOnlyIndexReader) readOnlyReaders.get(deleted);
+ if (cachedReadOnlyIndexReader == null) {
+ cachedReadOnlyIndexReader = new ReadOnlyIndexReader(sharedReader, deleted);
+ readOnlyReaders.put(deleted, cachedReadOnlyIndexReader);
+ }
+ return cachedReadOnlyIndexReader;
}
/**
@@ -317,6 +327,7 @@
sharedReader.close();
sharedReader = null;
}
+ readOnlyReaders.clear();
}
/**
Index: src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java (revision 548680)
+++ src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java (working copy)
@@ -175,7 +175,15 @@
System.arraycopy(subReaders, 0, readers, 0, subReaders.length);
return readers;
}
+
+ public IndexReader getSubReader(int doc) {
+ return subReaders[readerIndex(doc)];
+ }
+ public int getSubReaderDocNum(int doc) {
+ return doc - starts[readerIndex(doc)];
+ }
+
//------------------------< internal >--------------------------------------
/**
Index: src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java (revision 548680)
+++ src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java (working copy)
@@ -992,6 +992,29 @@
return hi;
}
+ public IndexReader getBaseReader(int doc) {
+ int i = readerIndex(doc);
+ CachingMultiReader subReader = subReaders[i];
+ return subReader.getSubReader(doc - starts[i]);
+ }
+
+ public int getBaseReaderDocNum(int doc) {
+ int i = readerIndex(doc);
+ CachingMultiReader subReader = subReaders[i];
+ return subReader.getSubReaderDocNum(doc);
+ }
+
+ public IndexReader[] getBaseReaders() {
+ List list = new ArrayList();
+ for (int i = 0; i < subReaders.length; i++) {
+ IndexReader[] indexReaders = subReaders[i].getIndexReaders();
+ for (int j = 0; j < indexReaders.length; j++) {
+ list.add(indexReaders[j]);
+ }
+ }
+ return (IndexReader[]) list.toArray(new IndexReader[0]);
+ }
+
public boolean equals(Object obj) {
if (obj instanceof CombinedIndexReader) {
CombinedIndexReader other = (CombinedIndexReader) obj;
Index: src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java (revision 548680)
+++ src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java (working copy)
@@ -20,7 +20,6 @@
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermEnum;
-import org.apache.lucene.search.FieldCache;
import org.apache.lucene.search.SortComparator;
import java.io.IOException;
@@ -38,6 +37,22 @@
*/
class SharedFieldCache {
+ /** Expert: Stores term text values and document ordering data. */
+ public static class StringIndex {
+
+ /** All the term values, in natural order. */
+ public final String[] lookup;
+
+ /** Terms indexed by document id. */
+ public final String[] terms;
+
+ /** Creates one of these objects */
+ public StringIndex(String[] terms, String[] lookup) {
+ this.terms = terms;
+ this.lookup = lookup;
+ }
+ }
+
/**
* Reference to the single instance of SharedFieldCache.
*/
@@ -72,7 +87,7 @@
* information.
* @throws IOException if an error occurs while reading from the index.
*/
- public FieldCache.StringIndex getStringIndex(IndexReader reader,
+ public SharedFieldCache.StringIndex getStringIndex(IndexReader reader,
String field,
String prefix,
SortComparator comparator,
@@ -79,9 +94,9 @@
boolean includeLookup)
throws IOException {
field = field.intern();
- FieldCache.StringIndex ret = lookup(reader, field, prefix, comparator);
+ SharedFieldCache.StringIndex ret = lookup(reader, field, prefix, comparator);
if (ret == null) {
- final int[] retArray = new int[reader.maxDoc()];
+ final String[] retArray = new String[reader.maxDoc()];
List mterms = null;
if (includeLookup) {
mterms = new ArrayList();
@@ -95,7 +110,6 @@
if (includeLookup) {
mterms.add(null); // for documents with term number 0
}
- int t = 1; // current term number
try {
if (termEnum.term() == null) {
@@ -114,10 +128,8 @@
termDocs.seek(termEnum);
while (termDocs.next()) {
- retArray[termDocs.doc()] = t;
+ retArray[termDocs.doc()] = term.text().substring(prefix.length());
}
-
- t++;
} while (termEnum.next());
} finally {
termDocs.close();
@@ -128,7 +140,7 @@
if (includeLookup) {
lookup = (String[]) mterms.toArray(new String[mterms.size()]);
}
- FieldCache.StringIndex value = new FieldCache.StringIndex(retArray, lookup);
+ SharedFieldCache.StringIndex value = new SharedFieldCache.StringIndex(retArray, lookup);
store(reader, field, prefix, comparator, value);
return value;
}
@@ -138,7 +150,7 @@
/**
* See if a StringIndex object is in the cache.
*/
- FieldCache.StringIndex lookup(IndexReader reader, String field,
+ SharedFieldCache.StringIndex lookup(IndexReader reader, String field,
String prefix, SortComparator comparer) {
Key key = new Key(field, prefix, comparer);
synchronized (this) {
@@ -146,7 +158,7 @@
if (readerCache == null) {
return null;
}
- return (FieldCache.StringIndex) readerCache.get(key);
+ return (SharedFieldCache.StringIndex) readerCache.get(key);
}
}
@@ -154,7 +166,7 @@
* Put a StringIndex value to cache.
*/
Object store(IndexReader reader, String field, String prefix,
- SortComparator comparer, FieldCache.StringIndex value) {
+ SortComparator comparer, SharedFieldCache.StringIndex value) {
Key key = new Key(field, prefix, comparer);
synchronized (this) {
HashMap readerCache = (HashMap) cache.get(reader);
Index: src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java (revision 548680)
+++ src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java (working copy)
@@ -16,8 +16,9 @@
*/
package org.apache.jackrabbit.core.query.lucene;
+import org.apache.jackrabbit.core.query.lucene.SearchIndex.CombinedIndexReader;
+import org.apache.jackrabbit.core.query.lucene.SharedFieldCache.StringIndex;
import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.search.FieldCache;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.ScoreDocComparator;
import org.apache.lucene.search.SortComparator;
@@ -24,6 +25,7 @@
import org.apache.lucene.search.SortField;
import java.io.IOException;
+import java.util.HashMap;
/**
* Implements a SortComparator which knows how to sort on a lucene
@@ -88,26 +90,48 @@
* @return a ScoreDocComparator for the
* @throws IOException
*/
- public ScoreDocComparator newComparator(final IndexReader reader, String propertyName)
- throws IOException {
- // get the StringIndex for propertyName
- final FieldCache.StringIndex index
- = SharedFieldCache.INSTANCE.getStringIndex(reader, field,
- FieldNames.createNamedValue(propertyName, ""),
- SharedFieldSortComparator.this,
- createComparatorValues);
-
+ public ScoreDocComparator newComparator(final IndexReader reader, final String propertyName) {
+
return new ScoreDocComparator() {
+
+ private CombinedIndexReader combinedIndexReader = ((CombinedIndexReader) reader);
+ private HashMap indexes = new HashMap();
+
public final int compare(final ScoreDoc i, final ScoreDoc j) {
- final int fi = index.order[i.doc];
- final int fj = index.order[j.doc];
- if (fi < fj) {
- return -1;
- } else if (fi > fj) {
- return 1;
- } else {
- return 0;
+ int iBaseReaderDoc = combinedIndexReader.getBaseReaderDocNum(i.doc);
+ SharedFieldCache.StringIndex iIndex = getIndex(i.doc);
+
+ int jBaseReaderDoc = combinedIndexReader.getBaseReaderDocNum(j.doc);
+ SharedFieldCache.StringIndex jIndex = getIndex(j.doc);
+
+ String iTerm = iIndex.terms[iBaseReaderDoc];
+ String jTerm = jIndex.terms[jBaseReaderDoc];
+
+ if (iTerm == jTerm) return 0;
+ if (iTerm == null) return -1;
+ if (jTerm == null) return 1;
+
+ return iTerm.compareTo(jTerm);
+ }
+
+ private SharedFieldCache.StringIndex getIndex(int doc) {
+ IndexReader baseReader = combinedIndexReader.getBaseReader(doc);
+ StringIndex cachedIndex = (StringIndex) indexes.get(baseReader);
+
+ if (cachedIndex == null) {
+ try {
+ // get the StringIndex for propertyName
+ cachedIndex = SharedFieldCache.INSTANCE.getStringIndex(baseReader, field,
+ FieldNames.createNamedValue(propertyName, ""),
+ SharedFieldSortComparator.this,
+ createComparatorValues);
+ indexes.put(baseReader, cachedIndex);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
+
+ return cachedIndex;
}
/**
@@ -118,8 +142,9 @@
* @return the sort value if available.
*/
public Comparable sortValue(final ScoreDoc i) {
+ StringIndex index = getIndex(i.doc);
if (index.lookup != null) {
- return index.lookup[index.order[i.doc]];
+ return index.terms[i.doc];
} else {
// return dummy value
return "";