Performance improvement - mainly for PATHs ending * - cache isNode lookup - ENH-378

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14025 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Andrew Hind
2009-04-21 09:43:01 +00:00
parent 966201871c
commit ae5ef978d7
6 changed files with 434 additions and 72 deletions

View File

@@ -42,6 +42,7 @@ import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Searcher; import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TermQuery;
import org.apache.lucene.util.OpenBitSet;
/** /**
@@ -54,7 +55,7 @@ public class FilterIndexReaderByStringId extends FilterIndexReader
{ {
private static Log s_logger = LogFactory.getLog(FilterIndexReaderByStringId.class); private static Log s_logger = LogFactory.getLog(FilterIndexReaderByStringId.class);
BitSet deletedDocuments; OpenBitSet deletedDocuments;
private String id; private String id;
@@ -71,7 +72,7 @@ public class FilterIndexReaderByStringId extends FilterIndexReader
super(reader); super(reader);
this.id = id; this.id = id;
deletedDocuments = new BitSet(reader.maxDoc()); deletedDocuments = new OpenBitSet(reader.maxDoc());
if (s_logger.isDebugEnabled()) if (s_logger.isDebugEnabled())
{ {
@@ -87,7 +88,7 @@ public class FilterIndexReaderByStringId extends FilterIndexReader
TermDocs td = reader.termDocs(new Term("ID", stringRef)); TermDocs td = reader.termDocs(new Term("ID", stringRef));
while (td.next()) while (td.next())
{ {
deletedDocuments.set(td.doc(), true); deletedDocuments.set(td.doc());
} }
} }
} }
@@ -106,7 +107,7 @@ public class FilterIndexReaderByStringId extends FilterIndexReader
Document doc = hits.doc(i); Document doc = hits.doc(i);
if (doc.getField("ISCONTAINER") == null) if (doc.getField("ISCONTAINER") == null)
{ {
deletedDocuments.set(hits.id(i), true); deletedDocuments.set(hits.id(i));
// There should only be one thing to delete // There should only be one thing to delete
// break; // break;
} }
@@ -131,7 +132,7 @@ public class FilterIndexReaderByStringId extends FilterIndexReader
*/ */
public static class FilterTermDocs implements TermDocs public static class FilterTermDocs implements TermDocs
{ {
BitSet deletedDocuments; OpenBitSet deletedDocuments;
protected TermDocs in; protected TermDocs in;
@@ -142,7 +143,7 @@ public class FilterIndexReaderByStringId extends FilterIndexReader
* @param in * @param in
* @param deletedDocuments * @param deletedDocuments
*/ */
public FilterTermDocs(String id, TermDocs in, BitSet deletedDocuments) public FilterTermDocs(String id, TermDocs in, OpenBitSet deletedDocuments)
{ {
this.in = in; this.in = in;
this.deletedDocuments = deletedDocuments; this.deletedDocuments = deletedDocuments;
@@ -268,41 +269,44 @@ public class FilterIndexReaderByStringId extends FilterIndexReader
public static class FilterTermPositions extends FilterTermDocs implements TermPositions public static class FilterTermPositions extends FilterTermDocs implements TermPositions
{ {
TermPositions tp;
/** /**
* @param id * @param id
* @param in * @param in
* @param deletedDocuements * @param deletedDocuements
*/ */
public FilterTermPositions(String id, TermPositions in, BitSet deletedDocuements) public FilterTermPositions(String id, TermPositions in, OpenBitSet deletedDocuements)
{ {
super(id, in, deletedDocuements); super(id, in, deletedDocuements);
tp = in;
} }
public int nextPosition() throws IOException public int nextPosition() throws IOException
{ {
return ((TermPositions) this.in).nextPosition(); return tp.nextPosition();
} }
public byte[] getPayload(byte[] data, int offset) throws IOException public byte[] getPayload(byte[] data, int offset) throws IOException
{ {
return ((TermPositions) this.in).getPayload(data, offset); return tp.getPayload(data, offset);
} }
public int getPayloadLength() public int getPayloadLength()
{ {
return ((TermPositions) this.in).getPayloadLength(); return tp.getPayloadLength();
} }
public boolean isPayloadAvailable() public boolean isPayloadAvailable()
{ {
return ((TermPositions) this.in).isPayloadAvailable(); return tp.isPayloadAvailable();
} }
} }
@Override @Override
public int numDocs() public int numDocs()
{ {
return super.numDocs() - deletedDocuments.cardinality(); return super.numDocs() - (int)deletedDocuments.cardinality();
} }
@Override @Override

View File

@@ -26,6 +26,8 @@ package org.alfresco.repo.search.impl.lucene.index;
import java.io.IOException; import java.io.IOException;
import org.apache.lucene.index.TermDocs;
/** /**
* *
* @author andyh * @author andyh
@@ -49,4 +51,6 @@ public interface CachingIndexReader
public String getType(int n) throws IOException; public String getType(int n) throws IOException;
public TermDocs getNodeDocs() throws IOException;
} }

View File

@@ -64,7 +64,12 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.search.IndexerException; import org.alfresco.repo.search.IndexerException;
import org.alfresco.repo.search.impl.lucene.FilterIndexReaderByStringId; import org.alfresco.repo.search.impl.lucene.FilterIndexReaderByStringId;
import org.alfresco.repo.search.impl.lucene.LuceneConfig; import org.alfresco.repo.search.impl.lucene.LuceneConfig;
import org.alfresco.repo.search.impl.lucene.LuceneXPathHandler;
import org.alfresco.repo.search.impl.lucene.analysis.AlfrescoStandardAnalyser; import org.alfresco.repo.search.impl.lucene.analysis.AlfrescoStandardAnalyser;
import org.alfresco.repo.search.impl.lucene.query.PathQuery;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
import org.alfresco.util.TraceableThreadFactory; import org.alfresco.util.TraceableThreadFactory;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@@ -78,22 +83,28 @@ import org.apache.lucene.index.MultiReader;
import org.apache.lucene.index.SerialMergeScheduler; import org.apache.lucene.index.SerialMergeScheduler;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermEnum; import org.apache.lucene.index.TermEnum;
import org.apache.lucene.index.IndexReader.FieldOption;
import org.apache.lucene.index.IndexWriter.MaxFieldLength; import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.search.Hits; import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Searcher; import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory; import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.IndexInput; import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput; import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.store.RAMDirectory;
import org.safehaus.uuid.UUID; import org.safehaus.uuid.UUID;
import org.saxpath.SAXPathException;
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.ContextRefreshedEvent;
import com.werken.saxpath.XPathReader;
/** /**
* The information that makes up an index. IndexInfoVersion Repeated information of the form * The information that makes up an index. IndexInfoVersion Repeated information of the form
* <ol> * <ol>
@@ -177,7 +188,7 @@ public class IndexInfo implements IndexMonitor
* The directory relative to the root path * The directory relative to the root path
*/ */
private String relativePath; private String relativePath;
/** /**
* The file holding the index information * The file holding the index information
*/ */
@@ -326,9 +337,9 @@ public class IndexInfo implements IndexMonitor
private ThreadPoolExecutor threadPoolExecutor; private ThreadPoolExecutor threadPoolExecutor;
private LuceneConfig config; private LuceneConfig config;
private List<ApplicationListener> applicationListeners = new LinkedList<ApplicationListener>(); private List<ApplicationListener> applicationListeners = new LinkedList<ApplicationListener>();
static static
{ {
// We do not require any of the lucene in-built locking. // We do not require any of the lucene in-built locking.
@@ -406,7 +417,7 @@ public class IndexInfo implements IndexMonitor
catch (IOException e) catch (IOException e)
{ {
throw new AlfrescoRuntimeException("Failed to determine index relative path", e); throw new AlfrescoRuntimeException("Failed to determine index relative path", e);
} }
} }
else else
{ {
@@ -438,7 +449,7 @@ public class IndexInfo implements IndexMonitor
{ {
throw new AlfrescoRuntimeException("Failed to determine index relative path", e); throw new AlfrescoRuntimeException("Failed to determine index relative path", e);
} }
} }
// Create an empty in memory index // Create an empty in memory index
@@ -476,7 +487,7 @@ public class IndexInfo implements IndexMonitor
{ {
throw new AlfrescoRuntimeException("The index must be held in a directory"); throw new AlfrescoRuntimeException("The index must be held in a directory");
} }
// Create the info files. // Create the info files.
File indexInfoFile = new File(this.indexDirectory, INDEX_INFO); File indexInfoFile = new File(this.indexDirectory, INDEX_INFO);
File indexInfoBackupFile = new File(this.indexDirectory, INDEX_INFO_BACKUP); File indexInfoBackupFile = new File(this.indexDirectory, INDEX_INFO_BACKUP);
@@ -681,7 +692,7 @@ public class IndexInfo implements IndexMonitor
cleaner.schedule(); cleaner.schedule();
} }
}, 0, 20000); }, 0, 20000);
publishDiscoveryEvent(); publishDiscoveryEvent();
} }
@@ -691,6 +702,7 @@ public class IndexInfo implements IndexMonitor
{ {
return true; return true;
} }
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
setStatusFromFile(); setStatusFromFile();
@@ -1926,15 +1938,15 @@ public class IndexInfo implements IndexMonitor
File location = new File(indexDirectory, id).getCanonicalFile(); File location = new File(indexDirectory, id).getCanonicalFile();
if (IndexReader.indexExists(location)) if (IndexReader.indexExists(location))
{ {
if ((config != null) && (size > config.getMaxDocsForInMemoryMerge())) if ((config != null) && (size < config.getMaxDocsForInMemoryMerge()))
{
reader = IndexReader.open(location);
}
else
{ {
RAMDirectory rd = new RAMDirectory(location); RAMDirectory rd = new RAMDirectory(location);
reader = IndexReader.open(rd); reader = IndexReader.open(rd);
} }
else
{
reader = IndexReader.open(location);
}
} }
else else
{ {
@@ -2436,9 +2448,25 @@ public class IndexInfo implements IndexMonitor
readIndexInfo(indexLocation); readIndexInfo(indexLocation);
} }
} }
static Query getPathQuery(String path) throws SAXPathException
{
ConfigurableApplicationContext ac = ApplicationContextHelper.getApplicationContext();
XPathReader reader = new XPathReader();
LuceneXPathHandler handler = new LuceneXPathHandler();
handler.setNamespacePrefixResolver((NamespaceService)ac.getBean("namespaceService"));
handler.setDictionaryService((DictionaryService)ac.getBean("dictionaryService"));
reader.setXPathHandler(handler);
reader.parse(path);
PathQuery pathQuery = handler.getQuery();
pathQuery.setRepeats(false);
return pathQuery;
}
private static void readIndexInfo(File indexLocation) throws Throwable private static void readIndexInfo(File indexLocation) throws Throwable
{ {
long start;
long end;
IndexInfo ii = new IndexInfo(indexLocation, null); IndexInfo ii = new IndexInfo(indexLocation, null);
ii.readWriteLock.writeLock().lock(); ii.readWriteLock.writeLock().lock();
@@ -2457,16 +2485,228 @@ public class IndexInfo implements IndexMonitor
ii.releaseWriteLock(); ii.releaseWriteLock();
} }
IndexReader reader = ii.getMainIndexReferenceCountingReadOnlyIndexReader(); IndexReader reader = ii.getMainIndexReferenceCountingReadOnlyIndexReader();
TermEnum terms = reader.terms(new Term("@{http://www.alfresco.org/model/user/1.0}members", "")); System.out.println(reader.getFieldNames(FieldOption.ALL));
while (terms.next() && terms.term().field().equals("@{http://www.alfresco.org/model/user/1.0}members")) IndexSearcher searcher = new IndexSearcher(reader);
{ Query query = new TermQuery(new Term("@{http://www.travelmuse.com/wcm}DestinationName", "bambino"));
System.out.println("F = " + terms.term().field() + " V = " + terms.term().text() + " F = " + terms.docFreq()); start = System.nanoTime();
if (terms.term().text().equals("xirmsi")) Hits hits = searcher.search(query);
{ end = System.nanoTime();
System.out.println("Matched"); System.out.println("@{http://www.travelmuse.com/wcm}DestinationName:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
} searcher.close();
}
terms.close(); searcher = new IndexSearcher(reader);
query = new TermQuery(new Term("@{http://www.travelmuse.com/wcm}DestinationName", "bambino"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.travelmuse.com/wcm}DestinationName:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new WildcardQuery(new Term("@{http://www.travelmuse.com/wcm}DestinationPhoto", "*"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.travelmuse.com/wcm}DestinationPhoto:* = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new WildcardQuery(new Term("@{http://www.travelmuse.com/wcm}DestinationPhoto", "*"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.travelmuse.com/wcm}DestinationPhoto:* = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new TermQuery(new Term("@{http://www.travelmuse.com/wcm}ThemeName", "bambino"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.travelmuse.com/wcm}ThemeName:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new TermQuery(new Term("@{http://www.travelmuse.com/wcm}ThemeName", "bambino"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.travelmuse.com/wcm}ThemeName:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new TermQuery(new Term("@{http://www.travelmuse.com/wcm}ActivityName", "bambino"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.travelmuse.com/wcm}ActivityName:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new TermQuery(new Term("@{http://www.travelmuse.com/wcm}ActivityName", "bambino"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.travelmuse.com/wcm}ActivityName:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new TermQuery(new Term("@{http://www.travelmuse.com/wcm}EditorialItemTitle", "bambino"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.travelmuse.com/wcm}EditorialItemTitle:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new TermQuery(new Term("@{http://www.travelmuse.com/wcm}EditorialItemTitle", "bambino"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.travelmuse.com/wcm}EditorialItemTitle:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new TermQuery(new Term("@{http://www.travelmuse.com/wcm}PoiName", "bambino"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.travelmuse.com/wcm}PoiName:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new TermQuery(new Term("@{http://www.travelmuse.com/wcm}PoiName", "bambino"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.travelmuse.com/wcm}PoiName:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new TermQuery(new Term("@{http://www.travelmuse.com/wcm}PropertyName", "bambino"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.travelmuse.com/wcm}PropertyName:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new TermQuery(new Term("@{http://www.travelmuse.com/wcm}PropertyName", "bambino"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.travelmuse.com/wcm}PropertyName:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new TermQuery(new Term("@{http://www.alfresco.org/model/content/1.0}content", "bambino"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.alfresco.org/model/content/1.0}content:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = new TermQuery(new Term("@{http://www.alfresco.org/model/content/1.0}content", "bambino"));
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("@{http://www.alfresco.org/model/content/1.0}content:bambino = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = getPathQuery("/www/avm_webapps/ROOT/editorial//*");
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("/www/avm_webapps/ROOT/editorial//* = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = getPathQuery("/www/avm_webapps/ROOT/editorial//*");
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("/www/avm_webapps/ROOT/editorial//* = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = getPathQuery("/www/avm_webapps/ROOT/tag//*");
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("/www/avm_webapps/ROOT/tag//* = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = getPathQuery("/www/avm_webapps/ROOT/tag//*");
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("/www/avm_webapps/ROOT/tag//* = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = getPathQuery("/www/avm_webapps/ROOT/poi//*");
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("/www/avm_webapps/ROOT/poi//* = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = getPathQuery("/www/avm_webapps/ROOT/poi//*");
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("/www/avm_webapps/ROOT/poi//* = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = getPathQuery("/www/avm_webapps/ROOT/property//*");
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("/www/avm_webapps/ROOT/property//* = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = getPathQuery("/www/avm_webapps/ROOT/property//*");
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("/www/avm_webapps/ROOT/property//* = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = getPathQuery("/www/avm_webapps/ROOT/web-reviews//*");
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("/www/avm_webapps/ROOT/web-reviews//* = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
searcher = new IndexSearcher(reader);
query = getPathQuery("/www/avm_webapps/ROOT/web-reviews//*");
start = System.nanoTime();
hits = searcher.search(query);
end = System.nanoTime();
System.out.println("/www/avm_webapps/ROOT/web-reviews//* = " + hits.length() + " in " + ((end - start) / 1e9));
searcher.close();
// TermEnum terms = reader.terms(new Term("@{http://www.alfresco.org/model/user/1.0}members", ""));
// while (terms.next() && terms.term().field().equals("@{http://www.alfresco.org/model/user/1.0}members"))
// {
// System.out.println("F = " + terms.term().field() + " V = " + terms.term().text() + " F = " +
// terms.docFreq());
// if (terms.term().text().equals("xirmsi"))
// {
// System.out.println("Matched");
// }
// }
// terms.close();
} }
@@ -3290,7 +3530,7 @@ public class IndexInfo implements IndexMonitor
} }
dumpInfo(); dumpInfo();
notifyListeners("MergedDeletions", toDelete.size()); notifyListeners("MergedDeletions", toDelete.size());
return null; return null;
@@ -3302,7 +3542,7 @@ public class IndexInfo implements IndexMonitor
} }
}); });
} }
finally finally
{ {
@@ -3551,7 +3791,7 @@ public class IndexInfo implements IndexMonitor
registerReferenceCountingIndexReader(finalMergeTargetId, finalNewReader); registerReferenceCountingIndexReader(finalMergeTargetId, finalNewReader);
notifyListeners("MergedIndexes", toMerge.size()); notifyListeners("MergedIndexes", toMerge.size());
dumpInfo(); dumpInfo();
writeStatus(); writeStatus();
@@ -3710,9 +3950,10 @@ public class IndexInfo implements IndexMonitor
} }
return false; return false;
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
*
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getRelativePath() * @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getRelativePath()
*/ */
public String getRelativePath() public String getRelativePath()
@@ -3720,7 +3961,9 @@ public class IndexInfo implements IndexMonitor
return this.relativePath; return this.relativePath;
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getStatusSnapshot() * @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getStatusSnapshot()
*/ */
public Map<String, Integer> getStatusSnapshot() public Map<String, Integer> getStatusSnapshot()
@@ -3740,10 +3983,12 @@ public class IndexInfo implements IndexMonitor
finally finally
{ {
readWriteLock.writeLock().unlock(); readWriteLock.writeLock().unlock();
} }
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getActualSize() * @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getActualSize()
*/ */
public long getActualSize() throws IOException public long getActualSize() throws IOException
@@ -3772,7 +4017,9 @@ public class IndexInfo implements IndexMonitor
} }
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getUsedSize() * @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getUsedSize()
*/ */
public long getUsedSize() throws IOException public long getUsedSize() throws IOException
@@ -3787,8 +4034,10 @@ public class IndexInfo implements IndexMonitor
releaseReadLock(); releaseReadLock();
} }
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getNumberOfDocuments() * @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getNumberOfDocuments()
*/ */
public int getNumberOfDocuments() throws IOException public int getNumberOfDocuments() throws IOException
@@ -3804,12 +4053,14 @@ public class IndexInfo implements IndexMonitor
} }
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getNumberOfFields() * @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getNumberOfFields()
*/ */
public int getNumberOfFields() throws IOException public int getNumberOfFields() throws IOException
{ {
IndexReader reader = getMainIndexReferenceCountingReadOnlyIndexReader(); IndexReader reader = getMainIndexReferenceCountingReadOnlyIndexReader();
try try
{ {
@@ -3821,7 +4072,9 @@ public class IndexInfo implements IndexMonitor
} }
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getNumberOfIndexedFields() * @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#getNumberOfIndexedFields()
*/ */
public int getNumberOfIndexedFields() throws IOException public int getNumberOfIndexedFields() throws IOException
@@ -3839,8 +4092,9 @@ public class IndexInfo implements IndexMonitor
/* /*
* (non-Javadoc) * (non-Javadoc)
*
* @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#addApplicationListener(org.springframework.context. * @see org.alfresco.repo.search.impl.lucene.index.IndexMonitor#addApplicationListener(org.springframework.context.
* ApplicationListener) * ApplicationListener)
*/ */
public void addApplicationListener(ApplicationListener listener) public void addApplicationListener(ApplicationListener listener)
{ {
@@ -3864,7 +4118,7 @@ public class IndexInfo implements IndexMonitor
} }
return size; return size;
} }
private void publishDiscoveryEvent() private void publishDiscoveryEvent()
{ {
if (this.config == null) if (this.config == null)
@@ -3883,7 +4137,7 @@ public class IndexInfo implements IndexMonitor
// that will fire when it has // that will fire when it has
applicationContext.addApplicationListener(new ApplicationListener() applicationContext.addApplicationListener(new ApplicationListener()
{ {
public void onApplicationEvent(ApplicationEvent event) public void onApplicationEvent(ApplicationEvent event)
{ {
if (event instanceof ContextRefreshedEvent) if (event instanceof ContextRefreshedEvent)

View File

@@ -57,6 +57,10 @@ import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store; import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.FilterIndexReader; import org.apache.lucene.index.FilterIndexReader;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermEnum;
import org.apache.lucene.util.OpenBitSet;
public class ReferenceCountingReadOnlyIndexReaderFactory public class ReferenceCountingReadOnlyIndexReaderFactory
{ {
@@ -103,7 +107,7 @@ public class ReferenceCountingReadOnlyIndexReaderFactory
private static final long serialVersionUID = 7693185658022810428L; private static final long serialVersionUID = 7693185658022810428L;
private static java.lang.reflect.Field s_field; private static java.lang.reflect.Field s_field;
String id; String id;
int refCount = 0; int refCount = 0;
@@ -146,15 +150,16 @@ public class ReferenceCountingReadOnlyIndexReaderFactory
} }
catch (NoSuchFieldException e) catch (NoSuchFieldException e)
{ {
throw new AlfrescoRuntimeException("Reference counting index reader needs access to org.apache.lucene.index.IndexReader.closed to work correctly (incompatible version of lucene)", e); throw new AlfrescoRuntimeException(
"Reference counting index reader needs access to org.apache.lucene.index.IndexReader.closed to work correctly (incompatible version of lucene)", e);
} }
} }
ReferenceCountingReadOnlyIndexReader(String id, IndexReader indexReader, boolean enableCaching, LuceneConfig config) ReferenceCountingReadOnlyIndexReader(String id, IndexReader indexReader, boolean enableCaching, LuceneConfig config)
{ {
super(indexReader); super(indexReader);
this.id = id; this.id = id;
if(enableCaching && (config != null)) if (enableCaching && (config != null))
{ {
this.enableCaching = config.isCacheEnabled(); this.enableCaching = config.isCacheEnabled();
} }
@@ -172,7 +177,7 @@ public class ReferenceCountingReadOnlyIndexReaderFactory
{ {
s_logger.debug(Thread.currentThread().getName() + ": Reader " + id + " - increment - ref count is " + refCount + " ... " + super.toString()); s_logger.debug(Thread.currentThread().getName() + ": Reader " + id + " - increment - ref count is " + refCount + " ... " + super.toString());
} }
if(!wrapper_closed) if (!wrapper_closed)
{ {
try try
{ {
@@ -180,7 +185,7 @@ public class ReferenceCountingReadOnlyIndexReaderFactory
} }
catch (IllegalArgumentException e) catch (IllegalArgumentException e)
{ {
throw new AlfrescoRuntimeException("Failed to mark index as open ..", e); throw new AlfrescoRuntimeException("Failed to mark index as open ..", e);
} }
catch (IllegalAccessException e) catch (IllegalAccessException e)
{ {
@@ -269,7 +274,7 @@ public class ReferenceCountingReadOnlyIndexReaderFactory
throw new IllegalStateException(Thread.currentThread().getName() + "Indexer is closed " + id); throw new IllegalStateException(Thread.currentThread().getName() + "Indexer is closed " + id);
} }
decrementReferenceCount(); decrementReferenceCount();
if(!wrapper_closed) if (!wrapper_closed)
{ {
incRef(); incRef();
} }
@@ -351,6 +356,8 @@ public class ReferenceCountingReadOnlyIndexReaderFactory
private final MultipleValueFieldAccessor MV_LINKASPECT_FIELD_ACCESSOR = new MultipleValueFieldAccessor("LINKASPECT"); private final MultipleValueFieldAccessor MV_LINKASPECT_FIELD_ACCESSOR = new MultipleValueFieldAccessor("LINKASPECT");
private OpenBitSet nodes = null;
private <T> T manageCache(ConcurrentHashMap<Integer, WithUseCount<T>> cache, Accessor<T> accessor, int n, FieldSelector fieldSelector, int limit) throws IOException private <T> T manageCache(ConcurrentHashMap<Integer, WithUseCount<T>> cache, Accessor<T> accessor, int n, FieldSelector fieldSelector, int limit) throws IOException
{ {
Integer key = Integer.valueOf(n); Integer key = Integer.valueOf(n);
@@ -575,6 +582,21 @@ public class ReferenceCountingReadOnlyIndexReaderFactory
return answer.toArray(new String[answer.size()]); return answer.toArray(new String[answer.size()]);
} }
public synchronized TermDocs getNodeDocs() throws IOException
{
if (nodes == null)
{
TermDocs nodeDocs = termDocs(new Term("ISNODE", "T"));
nodes = new OpenBitSet();
while (nodeDocs.next())
{
nodes.set(nodeDocs.doc());
}
nodeDocs.close();
}
return new TermDocSet(nodes);
}
} }
static class WithUseCount<T> implements Comparable<WithUseCount<T>> static class WithUseCount<T> implements Comparable<WithUseCount<T>>
@@ -622,4 +644,68 @@ public class ReferenceCountingReadOnlyIndexReaderFactory
} }
} }
static class TermDocSet implements TermDocs
{
OpenBitSet set;
int position = -1;
TermDocSet(OpenBitSet set)
{
this.set = set;
}
public void close() throws IOException
{
// Noop
}
public int doc()
{
return position;
}
public int freq()
{
return 1;
}
public boolean next() throws IOException
{
position++;
position = set.nextSetBit(position);
return (position != -1);
}
public int read(int[] docs, int[] freqs) throws IOException
{
throw new UnsupportedOperationException();
}
public void seek(Term term) throws IOException
{
throw new UnsupportedOperationException();
}
public void seek(TermEnum termEnum) throws IOException
{
throw new UnsupportedOperationException();
}
public boolean skipTo(int target) throws IOException
{
do
{
if (!next())
{
return false;
}
}
while (target > doc());
return true;
}
}
} }

View File

@@ -49,6 +49,7 @@ import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermPositions; import org.apache.lucene.index.TermPositions;
import org.apache.lucene.search.Explanation; import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.Scorer; import org.apache.lucene.search.Scorer;
@@ -103,7 +104,7 @@ public class LeafScorer extends Scorer
IndexReader reader; IndexReader reader;
private TermPositions allNodes; private TermDocs allNodes;
TermPositions level0; TermPositions level0;
@@ -125,7 +126,7 @@ public class LeafScorer extends Scorer
private int[] cats; private int[] cats;
// private TermPositions tp; private boolean matchAllLeaves;
/** /**
* Constructor - should use an arg object ... * Constructor - should use an arg object ...
@@ -144,7 +145,7 @@ public class LeafScorer extends Scorer
* @param repeat * @param repeat
* @param tp * @param tp
*/ */
public LeafScorer(Weight weight, TermPositions root, TermPositions level0, ContainerScorer containerScorer, StructuredFieldPosition[] sfps, TermPositions allNodes, public LeafScorer(Weight weight, TermPositions root, TermPositions level0, ContainerScorer containerScorer, StructuredFieldPosition[] sfps, TermDocs allNodes,
HashMap<String, Counter> selfIds, IndexReader reader, Similarity similarity, byte[] norms, DictionaryService dictionaryService, boolean repeat, TermPositions tp) HashMap<String, Counter> selfIds, IndexReader reader, Similarity similarity, byte[] norms, DictionaryService dictionaryService, boolean repeat, TermPositions tp)
{ {
super(similarity); super(similarity);
@@ -167,6 +168,8 @@ public class LeafScorer extends Scorer
this.level0 = level0; this.level0 = level0;
this.dictionaryService = dictionaryService; this.dictionaryService = dictionaryService;
this.repeat = repeat; this.repeat = repeat;
matchAllLeaves = allNodes();
try try
{ {
initialise(); initialise();
@@ -388,7 +391,7 @@ public class LeafScorer extends Scorer
} }
} }
if (allNodes()) if (matchAllLeaves)
{ {
int position = 0; int position = 0;
parents = new int[10000]; parents = new int[10000];
@@ -513,11 +516,11 @@ public class LeafScorer extends Scorer
counter = 0; counter = 0;
} }
if (allNodes()) if (matchAllLeaves)
{ {
while (more) while (more)
{ {
if (allNodes.next() && root.next()) if (allNodes.next())
{ {
if (check()) if (check())
{ {
@@ -736,7 +739,7 @@ public class LeafScorer extends Scorer
private boolean check() throws IOException private boolean check() throws IOException
{ {
if (allNodes()) if (matchAllLeaves)
{ {
this.counter = 0; this.counter = 0;
int position; int position;
@@ -1027,7 +1030,7 @@ public class LeafScorer extends Scorer
public int doc() public int doc()
{ {
if (allNodes()) if (matchAllLeaves)
{ {
return allNodes.doc(); return allNodes.doc();
} }
@@ -1045,7 +1048,7 @@ public class LeafScorer extends Scorer
countInCounter = 1; countInCounter = 1;
counter = 0; counter = 0;
if (allNodes()) if (matchAllLeaves)
{ {
allNodes.skipTo(target); allNodes.skipTo(target);
root.skipTo(allNodes.doc()); // must match root.skipTo(allNodes.doc()); // must match
@@ -1055,7 +1058,7 @@ public class LeafScorer extends Scorer
} }
while (more) while (more)
{ {
if (allNodes.next() && root.next()) if (allNodes.next())
{ {
if (check()) if (check())
{ {

View File

@@ -28,12 +28,14 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import org.alfresco.repo.search.impl.lucene.index.CachingIndexReader;
import org.alfresco.repo.search.impl.lucene.query.LeafScorer.Counter; import org.alfresco.repo.search.impl.lucene.query.LeafScorer.Counter;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.apache.lucene.document.Document; import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermPositions; import org.apache.lucene.index.TermPositions;
import org.apache.lucene.search.Explanation; import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.Scorer; import org.apache.lucene.search.Scorer;
@@ -141,7 +143,16 @@ public class PathScorer extends Scorer
TermPositions level0 = null; TermPositions level0 = null;
TermPositions nodePositions = reader.termPositions(new Term("ISNODE", "T")); TermDocs nodeDocs;
if (reader instanceof CachingIndexReader)
{
CachingIndexReader cachingIndexReader = (CachingIndexReader) reader;
nodeDocs = cachingIndexReader.getNodeDocs();
}
else
{
nodeDocs = reader.termDocs(new Term("ISNODE", "T"));
}
// StructuredFieldPosition[] test = // StructuredFieldPosition[] test =
// (StructuredFieldPosition[])structuredFieldPositions.toArray(new // (StructuredFieldPosition[])structuredFieldPositions.toArray(new
@@ -160,11 +171,11 @@ public class PathScorer extends Scorer
if((cs == null) && if((cs == null) &&
(pathQuery.getQNameStructuredFieldPositions().get(pathQuery.getQNameStructuredFieldPositions().size()-1)).linkSelf()) (pathQuery.getQNameStructuredFieldPositions().get(pathQuery.getQNameStructuredFieldPositions().size()-1)).linkSelf())
{ {
nodePositions = reader.termPositions(new Term("ISROOT", "T")); nodeDocs = reader.termDocs(new Term("ISROOT", "T"));
} }
LeafScorer ls = new LeafScorer(weight, rootLeafPositions, level0, cs, (StructuredFieldPosition[]) pathQuery.getQNameStructuredFieldPositions().toArray(new StructuredFieldPosition[] {}), nodePositions, LeafScorer ls = new LeafScorer(weight, rootLeafPositions, level0, cs, (StructuredFieldPosition[]) pathQuery.getQNameStructuredFieldPositions().toArray(new StructuredFieldPosition[] {}), nodeDocs,
selfIds, reader, similarity, reader.norms(pathQuery.getQnameField()), dictionarySertvice, repeat, tp); selfIds, reader, similarity, reader.norms(pathQuery.getQnameField()), dictionarySertvice, repeat, tp);
return new PathScorer(similarity, ls); return new PathScorer(similarity, ls);