Index: lucene/facet/src/java/org/apache/lucene/facet/taxonomy/SearcherTaxonomyManager.java =================================================================== --- lucene/facet/src/java/org/apache/lucene/facet/taxonomy/SearcherTaxonomyManager.java (revision 1562788) +++ lucene/facet/src/java/org/apache/lucene/facet/taxonomy/SearcherTaxonomyManager.java (working copy) @@ -22,6 +22,7 @@ import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader; import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter; import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexNotFoundException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.search.IndexSearcher; @@ -28,6 +29,7 @@ import org.apache.lucene.search.ReferenceManager; import org.apache.lucene.search.SearcherFactory; import org.apache.lucene.search.SearcherManager; +import org.apache.lucene.store.Directory; import org.apache.lucene.util.IOUtils; /** @@ -69,11 +71,27 @@ this.searcherFactory = searcherFactory; this.taxoWriter = taxoWriter; DirectoryTaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoWriter); - current = new SearcherAndTaxonomy(SearcherManager.getSearcher(searcherFactory, DirectoryReader.open(writer, applyAllDeletes)), - taxoReader); - taxoEpoch = taxoWriter.getTaxonomyEpoch(); + current = new SearcherAndTaxonomy(SearcherManager.getSearcher(searcherFactory, DirectoryReader.open(writer, applyAllDeletes)), taxoReader); + this.taxoEpoch = taxoWriter.getTaxonomyEpoch(); } + /** + * Creates search and taxonomy readers over the corresponding directories. + * Note that you should only initialize the manage after both the search and + * taxonomy indexes were created, otherwise you will hit + * {@link IndexNotFoundException}. + */ + public SearcherTaxonomyManager(Directory indexDir, Directory taxoDir, SearcherFactory searcherFactory) throws IOException { + if (searcherFactory == null) { + searcherFactory = new SearcherFactory(); + } + this.searcherFactory = searcherFactory; + DirectoryTaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir); + current = new SearcherAndTaxonomy(SearcherManager.getSearcher(searcherFactory, DirectoryReader.open(indexDir)), taxoReader); + this.taxoWriter = null; + taxoEpoch = -1; + } + @Override protected void decRef(SearcherAndTaxonomy ref) throws IOException { ref.searcher.getIndexReader().decRef(); @@ -114,7 +132,7 @@ if (tr == null) { ref.taxonomyReader.incRef(); tr = ref.taxonomyReader; - } else if (taxoWriter.getTaxonomyEpoch() != taxoEpoch) { + } else if (taxoWriter != null && taxoWriter.getTaxonomyEpoch() != taxoEpoch) { IOUtils.close(newReader, tr); throw new IllegalStateException("DirectoryTaxonomyWriter.replaceTaxonomy was called, which is not allowed when using SearcherTaxonomyManager"); } Index: lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestSearcherTaxonomyManager.java =================================================================== --- lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestSearcherTaxonomyManager.java (revision 1562788) +++ lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestSearcherTaxonomyManager.java (working copy) @@ -42,7 +42,8 @@ import org.apache.lucene.util._TestUtil; public class TestSearcherTaxonomyManager extends FacetTestCase { - public void test() throws Exception { + + public void testNRT() throws Exception { Directory dir = newDirectory(); Directory taxoDir = newDirectory(); final IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()))); @@ -160,8 +161,108 @@ IOUtils.close(mgr, tw, w, taxoDir, dir); } + + public void testDirectory() throws Exception { + Directory indexDir = newDirectory(); + Directory taxoDir = newDirectory(); + final IndexWriter w = new IndexWriter(indexDir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()))); + final DirectoryTaxonomyWriter tw = new DirectoryTaxonomyWriter(taxoDir); + // first empty commit + w.commit(); + tw.commit(); + final SearcherTaxonomyManager mgr = new SearcherTaxonomyManager(indexDir, taxoDir, null); + final FacetsConfig config = new FacetsConfig(); + config.setMultiValued("field", true); + final AtomicBoolean stop = new AtomicBoolean(); - public void testReplaceTaxonomy() throws Exception { + // How many unique facets to index before stopping: + final int ordLimit = TEST_NIGHTLY ? 100000 : 6000; + + Thread indexer = new Thread() { + @Override + public void run() { + try { + Set seen = new HashSet(); + List paths = new ArrayList(); + while (true) { + Document doc = new Document(); + int numPaths = _TestUtil.nextInt(random(), 1, 5); + for(int i=0;i= ordLimit) { + break; + } + } + } finally { + stop.set(true); + } + } + }; + + indexer.start(); + + try { + while (!stop.get()) { + SearcherAndTaxonomy pair = mgr.acquire(); + try { + //System.out.println("search maxOrd=" + pair.taxonomyReader.getSize()); + FacetsCollector sfc = new FacetsCollector(); + pair.searcher.search(new MatchAllDocsQuery(), sfc); + Facets facets = getTaxonomyFacetCounts(pair.taxonomyReader, config, sfc); + FacetResult result = facets.getTopChildren(10, "field"); + if (pair.searcher.getIndexReader().numDocs() > 0) { + //System.out.println(pair.taxonomyReader.getSize()); + assertTrue(result.childCount > 0); + assertTrue(result.labelValues.length > 0); + } + + //if (VERBOSE) { + //System.out.println("TEST: facets=" + FacetTestUtils.toString(results.get(0))); + //} + } finally { + mgr.release(pair); + } + } + } finally { + indexer.join(); + } + + if (VERBOSE) { + System.out.println("TEST: now stop"); + } + + IOUtils.close(mgr, tw, w, taxoDir, indexDir); + } + + public void testReplaceTaxonomyNRT() throws Exception { Directory dir = newDirectory(); Directory taxoDir = newDirectory(); IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()))); @@ -185,4 +286,43 @@ IOUtils.close(mgr, tw, w, taxoDir, dir); } + + public void testReplaceTaxonomyDirectory() throws Exception { + Directory indexDir = newDirectory(); + Directory taxoDir = newDirectory(); + IndexWriter w = new IndexWriter(indexDir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()))); + DirectoryTaxonomyWriter tw = new DirectoryTaxonomyWriter(taxoDir); + w.commit(); + tw.commit(); + + Directory taxoDir2 = newDirectory(); + DirectoryTaxonomyWriter tw2 = new DirectoryTaxonomyWriter(taxoDir2); + tw2.addCategory(new FacetLabel("a", "b")); + tw2.close(); + + SearcherTaxonomyManager mgr = new SearcherTaxonomyManager(indexDir, taxoDir, null); + SearcherAndTaxonomy pair = mgr.acquire(); + try { + assertEquals(1, pair.taxonomyReader.getSize()); + } finally { + mgr.release(pair); + } + + w.addDocument(new Document()); + tw.replaceTaxonomy(taxoDir2); + taxoDir2.close(); + w.commit(); + tw.commit(); + + mgr.maybeRefresh(); + pair = mgr.acquire(); + try { + assertEquals(3, pair.taxonomyReader.getSize()); + } finally { + mgr.release(pair); + } + + IOUtils.close(mgr, tw, w, taxoDir, indexDir); + } + }