You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by sy...@apache.org on 2014/12/31 20:12:17 UTC
[11/14] lucenenet git commit: Moving Lucene.Net.Facet tests to their
appropriate place
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/68aa9728/src/Lucene.Net.Tests.Facet/Taxonomy/TestCachedOrdinalsReader.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Facet/Taxonomy/TestCachedOrdinalsReader.cs b/src/Lucene.Net.Tests.Facet/Taxonomy/TestCachedOrdinalsReader.cs
new file mode 100644
index 0000000..d528276
--- /dev/null
+++ b/src/Lucene.Net.Tests.Facet/Taxonomy/TestCachedOrdinalsReader.cs
@@ -0,0 +1,116 @@
+using System;
+using System.IO;
+using System.Threading;
+using Lucene.Net.Support;
+using NUnit.Framework;
+
+namespace Lucene.Net.Facet.Taxonomy
+{
+
+ /*
+ * 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.
+ */
+
+ using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
+ using Document = Lucene.Net.Documents.Document;
+ using DirectoryTaxonomyWriter = Lucene.Net.Facet.Taxonomy.Directory.DirectoryTaxonomyWriter;
+ using AtomicReaderContext = Lucene.Net.Index.AtomicReaderContext;
+ using DirectoryReader = Lucene.Net.Index.DirectoryReader;
+ using IndexWriter = Lucene.Net.Index.IndexWriter;
+ using IndexWriterConfig = Lucene.Net.Index.IndexWriterConfig;
+ using Directory = Lucene.Net.Store.Directory;
+ using IOUtils = Lucene.Net.Util.IOUtils;
+ [TestFixture]
+ public class TestCachedOrdinalsReader : FacetTestCase
+ {
+
+ [Test]
+ public virtual void TestWithThreads()
+ {
+ // LUCENE-5303: OrdinalsCache used the ThreadLocal BinaryDV instead of reader.getCoreCacheKey().
+ Store.Directory indexDir = NewDirectory();
+ Store.Directory taxoDir = NewDirectory();
+ IndexWriterConfig conf = NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random()));
+ IndexWriter writer = new IndexWriter(indexDir, conf);
+ var taxoWriter = new DirectoryTaxonomyWriter(taxoDir);
+ FacetsConfig config = new FacetsConfig();
+
+ Document doc = new Document();
+ doc.Add(new FacetField("A", "1"));
+ writer.AddDocument(config.Build(taxoWriter, doc));
+ doc = new Document();
+ doc.Add(new FacetField("A", "2"));
+ writer.AddDocument(config.Build(taxoWriter, doc));
+
+ var reader = DirectoryReader.Open(writer, true);
+ CachedOrdinalsReader ordsReader = new CachedOrdinalsReader(new DocValuesOrdinalsReader(FacetsConfig.DEFAULT_INDEX_FIELD_NAME));
+ ThreadClass[] threads = new ThreadClass[3];
+ for (int i = 0; i < threads.Length; i++)
+ {
+ threads[i] = new ThreadAnonymousInnerClassHelper(this, "CachedOrdsThread-" + i, reader, ordsReader);
+ }
+
+ long ramBytesUsed = 0;
+ foreach (ThreadClass t in threads)
+ {
+ t.Start();
+ t.Join();
+ if (ramBytesUsed == 0)
+ {
+ ramBytesUsed = ordsReader.RamBytesUsed();
+ }
+ else
+ {
+ Assert.AreEqual(ramBytesUsed, ordsReader.RamBytesUsed());
+ }
+ }
+
+ IOUtils.Close(writer, taxoWriter, reader, indexDir, taxoDir);
+ }
+
+ private class ThreadAnonymousInnerClassHelper : ThreadClass
+ {
+ private readonly TestCachedOrdinalsReader outerInstance;
+
+ private DirectoryReader reader;
+ private Lucene.Net.Facet.Taxonomy.CachedOrdinalsReader ordsReader;
+
+ public ThreadAnonymousInnerClassHelper(TestCachedOrdinalsReader outerInstance, string CachedOrdsThread, DirectoryReader reader, Lucene.Net.Facet.Taxonomy.CachedOrdinalsReader ordsReader)
+ : base("CachedOrdsThread-")
+ {
+ this.outerInstance = outerInstance;
+ this.reader = reader;
+ this.ordsReader = ordsReader;
+ }
+
+ public override void Run()
+ {
+ foreach (var context in reader.Leaves)
+ {
+ try
+ {
+ ordsReader.GetReader(context);
+ }
+ catch (IOException e)
+ {
+ throw new Exception(e.Message, e);
+ }
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/68aa9728/src/Lucene.Net.Tests.Facet/Taxonomy/TestFacetLabel.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Facet/Taxonomy/TestFacetLabel.cs b/src/Lucene.Net.Tests.Facet/Taxonomy/TestFacetLabel.cs
new file mode 100644
index 0000000..0226137
--- /dev/null
+++ b/src/Lucene.Net.Tests.Facet/Taxonomy/TestFacetLabel.cs
@@ -0,0 +1,360 @@
+using System;
+using Lucene.Net.Support;
+using NUnit.Framework;
+
+namespace Lucene.Net.Facet.Taxonomy
+{
+
+ using SortedSetDocValuesFacetField = Lucene.Net.Facet.SortedSet.SortedSetDocValuesFacetField;
+ using BytesRef = Lucene.Net.Util.BytesRef;
+ using TestUtil = Lucene.Net.Util.TestUtil;
+
+ /*
+ * 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.
+ */
+ [TestFixture]
+ public class TestFacetLabel : FacetTestCase
+ {
+
+ [Test]
+ public virtual void TestBasic()
+ {
+ Assert.AreEqual(0, (new FacetLabel()).Length);
+ Assert.AreEqual(1, (new FacetLabel("hello")).Length);
+ Assert.AreEqual(2, (new FacetLabel("hello", "world")).Length);
+ }
+
+ [Test]
+ public virtual void TestToString()
+ {
+ // When the category is empty, we expect an empty string
+ Assert.AreEqual("FacetLabel: []", (new FacetLabel()).ToString());
+ // one category
+ Assert.AreEqual("FacetLabel: [hello]", (new FacetLabel("hello")).ToString());
+ // more than one category
+ Assert.AreEqual("FacetLabel: [hello, world]", (new FacetLabel("hello", "world")).ToString());
+ }
+
+ [Test]
+ public virtual void TestGetComponent()
+ {
+ string[] components = new string[AtLeast(10)];
+ for (int i = 0; i < components.Length; i++)
+ {
+ components[i] = Convert.ToString(i);
+ }
+ FacetLabel cp = new FacetLabel(components);
+ for (int i = 0; i < components.Length; i++)
+ {
+ Assert.AreEqual(i, Convert.ToInt32(cp.Components[i]));
+ }
+ }
+
+ [Test]
+ public virtual void TestDefaultConstructor()
+ {
+ // test that the default constructor (no parameters) currently
+ // defaults to creating an object with a 0 initial capacity.
+ // If we change this default later, we also need to change this
+ // test.
+ FacetLabel p = new FacetLabel();
+ Assert.AreEqual(0, p.Length);
+ Assert.AreEqual("FacetLabel: []", p.ToString());
+ }
+
+ [Test]
+ public virtual void TestSubPath()
+ {
+ FacetLabel p = new FacetLabel("hi", "there", "man");
+ Assert.AreEqual(p.Length, 3);
+
+ FacetLabel p1 = p.Subpath(2);
+ Assert.AreEqual(2, p1.Length);
+ Assert.AreEqual("FacetLabel: [hi, there]", p1.ToString());
+
+ p1 = p.Subpath(1);
+ Assert.AreEqual(1, p1.Length);
+ Assert.AreEqual("FacetLabel: [hi]", p1.ToString());
+
+ p1 = p.Subpath(0);
+ Assert.AreEqual(0, p1.Length);
+ Assert.AreEqual("FacetLabel: []", p1.ToString());
+
+ // with all the following lengths, the prefix should be the whole path
+ int[] lengths = new int[] { 3, -1, 4 };
+ for (int i = 0; i < lengths.Length; i++)
+ {
+ p1 = p.Subpath(lengths[i]);
+ Assert.AreEqual(3, p1.Length);
+ Assert.AreEqual("FacetLabel: [hi, there, man]", p1.ToString());
+ Assert.AreEqual(p, p1);
+ }
+ }
+
+ [Test]
+ public virtual void TestEquals()
+ {
+ Assert.AreEqual(new FacetLabel(), new FacetLabel());
+ Assert.False((new FacetLabel()).Equals(new FacetLabel("hi")));
+ Assert.False((new FacetLabel()).Equals(Convert.ToInt32(3)));
+ Assert.AreEqual(new FacetLabel("hello", "world"), new FacetLabel("hello", "world"));
+ }
+
+ [Test]
+ public virtual void TestHashCode()
+ {
+ Assert.AreEqual((new FacetLabel()).GetHashCode(), (new FacetLabel()).GetHashCode());
+ Assert.False((new FacetLabel()).GetHashCode() == (new FacetLabel("hi")).GetHashCode());
+ Assert.AreEqual((new FacetLabel("hello", "world")).GetHashCode(), (new FacetLabel("hello", "world")).GetHashCode());
+ }
+
+ [Test]
+ public virtual void TestLongHashCode()
+ {
+ Assert.AreEqual((new FacetLabel()).LongHashCode(), (new FacetLabel()).LongHashCode());
+ Assert.False((new FacetLabel()).LongHashCode() == (new FacetLabel("hi")).LongHashCode());
+ Assert.AreEqual((new FacetLabel("hello", "world")).LongHashCode(), (new FacetLabel("hello", "world")).LongHashCode());
+ }
+
+ [Test]
+ public virtual void TestArrayConstructor()
+ {
+ FacetLabel p = new FacetLabel("hello", "world", "yo");
+ Assert.AreEqual(3, p.Length);
+ Assert.AreEqual("FacetLabel: [hello, world, yo]", p.ToString());
+ }
+
+ [Test]
+ public virtual void TestCompareTo()
+ {
+ FacetLabel p = new FacetLabel("a", "b", "c", "d");
+ FacetLabel pother = new FacetLabel("a", "b", "c", "d");
+ Assert.AreEqual(0, pother.CompareTo(p));
+ Assert.AreEqual(0, p.CompareTo(pother));
+ pother = new FacetLabel();
+ Assert.True(pother.CompareTo(p) < 0);
+ Assert.True(p.CompareTo(pother) > 0);
+ pother = new FacetLabel("a", "b_", "c", "d");
+ Assert.True(pother.CompareTo(p) > 0);
+ Assert.True(p.CompareTo(pother) < 0);
+ pother = new FacetLabel("a", "b", "c");
+ Assert.True(pother.CompareTo(p) < 0);
+ Assert.True(p.CompareTo(pother) > 0);
+ pother = new FacetLabel("a", "b", "c", "e");
+ Assert.True(pother.CompareTo(p) > 0);
+ Assert.True(p.CompareTo(pother) < 0);
+ }
+
+ [Test]
+ public virtual void TestEmptyNullComponents()
+ {
+ // LUCENE-4724: CategoryPath should not allow empty or null components
+ string[][] components_tests = new string[][]
+ {
+ new string[] {"", "test"},
+ new string[] {"test", ""},
+ new string[] {"test", "", "foo"},
+ new string[] {null, "test"},
+ new string[] {"test", null},
+ new string[] {"test", null, "foo"}
+ };
+
+ foreach (string[] components in components_tests)
+ {
+ try
+ {
+ Assert.NotNull(new FacetLabel(components));
+ Fail("empty or null components should not be allowed: " + Arrays.ToString(components));
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new FacetField("dim", components);
+ Fail("empty or null components should not be allowed: " + Arrays.ToString(components));
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new AssociationFacetField(new BytesRef(), "dim", components);
+ Fail("empty or null components should not be allowed: " + Arrays.ToString(components));
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new IntAssociationFacetField(17, "dim", components);
+ Fail("empty or null components should not be allowed: " + Arrays.ToString(components));
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new FloatAssociationFacetField(17.0f, "dim", components);
+ Fail("empty or null components should not be allowed: " + Arrays.ToString(components));
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ }
+ try
+ {
+ new FacetField(null, new string[] { "abc" });
+ Fail("empty or null components should not be allowed");
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new FacetField("", new string[] { "abc" });
+ Fail("empty or null components should not be allowed");
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new IntAssociationFacetField(17, null, new string[] { "abc" });
+ Fail("empty or null components should not be allowed");
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new IntAssociationFacetField(17, "", new string[] { "abc" });
+ Fail("empty or null components should not be allowed");
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new FloatAssociationFacetField(17.0f, null, new string[] { "abc" });
+ Fail("empty or null components should not be allowed");
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new FloatAssociationFacetField(17.0f, "", new string[] { "abc" });
+ Fail("empty or null components should not be allowed");
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new AssociationFacetField(new BytesRef(), null, new string[] { "abc" });
+ Fail("empty or null components should not be allowed");
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new AssociationFacetField(new BytesRef(), "", new string[] { "abc" });
+ Fail("empty or null components should not be allowed");
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new SortedSetDocValuesFacetField(null, "abc");
+ Fail("empty or null components should not be allowed");
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new SortedSetDocValuesFacetField("", "abc");
+ Fail("empty or null components should not be allowed");
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new SortedSetDocValuesFacetField("dim", null);
+ Fail("empty or null components should not be allowed");
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ try
+ {
+ new SortedSetDocValuesFacetField("dim", "");
+ Fail("empty or null components should not be allowed");
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ [Test]
+ public virtual void TestLongPath()
+ {
+ string bigComp = null;
+ while (true)
+ {
+ int len = FacetLabel.MAX_CATEGORY_PATH_LENGTH;
+ bigComp = TestUtil.RandomSimpleString(Random(), len, len);
+ if (bigComp.IndexOf('\u001f') != -1)
+ {
+ continue;
+ }
+ break;
+ }
+
+ try
+ {
+ Assert.NotNull(new FacetLabel("dim", bigComp));
+ Fail("long paths should not be allowed; len=" + bigComp.Length);
+ }
+ catch (System.ArgumentException)
+ {
+ // expected
+ }
+ }
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/68aa9728/src/Lucene.Net.Tests.Facet/Taxonomy/TestLRUHashMap.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Facet/Taxonomy/TestLRUHashMap.cs b/src/Lucene.Net.Tests.Facet/Taxonomy/TestLRUHashMap.cs
new file mode 100644
index 0000000..71b62c5
--- /dev/null
+++ b/src/Lucene.Net.Tests.Facet/Taxonomy/TestLRUHashMap.cs
@@ -0,0 +1,65 @@
+using NUnit.Framework;
+
+namespace Lucene.Net.Facet.Taxonomy
+{
+
+ /*
+ * 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.
+ */
+
+ using Lucene.Net.Facet.Taxonomy;
+ [TestFixture]
+ public class TestLRUHashMap : FacetTestCase
+ {
+ // testLRU() tests that the specified size limit is indeed honored, and
+ // the remaining objects in the map are indeed those that have been most
+ // recently used
+ [Test]
+ public virtual void TestLru()
+ {
+ LRUHashMap<string, string> lru = new LRUHashMap<string, string>(3,1);
+ Assert.AreEqual(0, lru.Size());
+ lru.Put("one", "Hello world");
+ Assert.AreEqual(1, lru.Size());
+ lru.Put("two", "Hi man");
+ Assert.AreEqual(2, lru.Size());
+ lru.Put("three", "Bonjour");
+ Assert.AreEqual(3, lru.Size());
+ lru.Put("four", "Shalom");
+ Assert.AreEqual(3, lru.Size());
+ Assert.NotNull(lru.Get("three"));
+ Assert.NotNull(lru.Get("two"));
+ Assert.NotNull(lru.Get("four"));
+ Assert.Null(lru.Get("one"));
+ lru.Put("five", "Yo!");
+ Assert.AreEqual(3, lru.Size());
+ Assert.Null(lru.Get("three")); // three was last used, so it got removed
+ Assert.NotNull(lru.Get("five"));
+ lru.Get("four");
+ lru.Put("six", "hi");
+ lru.Put("seven", "hey dude");
+ Assert.AreEqual(3, lru.Size());
+ Assert.Null(lru.Get("one"));
+ Assert.Null(lru.Get("two"));
+ Assert.Null(lru.Get("three"));
+ Assert.NotNull(lru.Get("four"));
+ Assert.Null(lru.Get("five"));
+ Assert.NotNull(lru.Get("six"));
+ Assert.NotNull(lru.Get("seven"));
+ }
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/68aa9728/src/Lucene.Net.Tests.Facet/Taxonomy/TestSearcherTaxonomyManager.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.Facet/Taxonomy/TestSearcherTaxonomyManager.cs b/src/Lucene.Net.Tests.Facet/Taxonomy/TestSearcherTaxonomyManager.cs
new file mode 100644
index 0000000..dd93d18
--- /dev/null
+++ b/src/Lucene.Net.Tests.Facet/Taxonomy/TestSearcherTaxonomyManager.cs
@@ -0,0 +1,398 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+using Apache.NMS;
+using Lucene.Net.Support;
+using NUnit.Framework;
+
+namespace Lucene.Net.Facet.Taxonomy
+{
+
+ /*
+ * 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.
+ */
+
+
+ using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
+ using Document = Lucene.Net.Documents.Document;
+ using SearcherAndTaxonomy = Lucene.Net.Facet.Taxonomy.SearcherTaxonomyManager.SearcherAndTaxonomy;
+ using DirectoryTaxonomyWriter = Lucene.Net.Facet.Taxonomy.Directory.DirectoryTaxonomyWriter;
+ using IndexWriter = Lucene.Net.Index.IndexWriter;
+ using IndexWriterConfig = Lucene.Net.Index.IndexWriterConfig;
+ using TieredMergePolicy = Lucene.Net.Index.TieredMergePolicy;
+ using MatchAllDocsQuery = Lucene.Net.Search.MatchAllDocsQuery;
+ using Lucene.Net.Search;
+ using Directory = Lucene.Net.Store.Directory;
+ using IOUtils = Lucene.Net.Util.IOUtils;
+ using TestUtil = Lucene.Net.Util.TestUtil;
+ [TestFixture]
+ public class TestSearcherTaxonomyManager : FacetTestCase
+ {
+
+ private class IndexerThread : ThreadClass
+ {
+
+ internal IndexWriter w;
+ internal FacetsConfig config;
+ internal TaxonomyWriter tw;
+ internal ReferenceManager<SearcherAndTaxonomy> mgr;
+ internal int ordLimit;
+ internal AtomicBoolean stop;
+
+ public IndexerThread(IndexWriter w, FacetsConfig config, TaxonomyWriter tw, ReferenceManager<SearcherAndTaxonomy> mgr, int ordLimit, AtomicBoolean stop)
+ {
+ this.w = w;
+ this.config = config;
+ this.tw = tw;
+ this.mgr = mgr;
+ this.ordLimit = ordLimit;
+ this.stop = stop;
+ }
+
+ public override void Run()
+ {
+ try
+ {
+ var seen = new HashSet<string>();
+ IList<string> paths = new List<string>();
+ while (true)
+ {
+ Document doc = new Document();
+ int numPaths = TestUtil.NextInt(Random(), 1, 5);
+ for (int i = 0; i < numPaths; i++)
+ {
+ string path;
+ if (paths.Count > 0 && Random().Next(5) != 4)
+ {
+ // Use previous path
+ path = paths[Random().Next(paths.Count)];
+ }
+ else
+ {
+ // Create new path
+ path = null;
+ while (true)
+ {
+ path = TestUtil.RandomRealisticUnicodeString(Random());
+ if (path.Length != 0 && !seen.Contains(path))
+ {
+ seen.Add(path);
+ paths.Add(path);
+ break;
+ }
+ }
+ }
+ doc.Add(new FacetField("field", path));
+ }
+ try
+ {
+ w.AddDocument(config.Build(tw, doc));
+ if (mgr != null && Random().NextDouble() < 0.02)
+ {
+ w.Commit();
+ tw.Commit();
+ mgr.MaybeRefresh();
+ }
+ }
+ catch (IOException ioe)
+ {
+ throw new Exception(ioe.Message, ioe);
+ }
+
+ if (VERBOSE)
+ {
+ Console.WriteLine("TW size=" + tw.Size + " vs " + ordLimit);
+ }
+
+ if (tw.Size >= ordLimit)
+ {
+ break;
+ }
+ }
+ }
+ finally
+ {
+ stop.Set(true);
+ }
+ }
+
+ }
+
+ [Test]
+ public virtual void TestNrt()
+ {
+ Store.Directory dir = NewDirectory();
+ Store.Directory taxoDir = NewDirectory();
+ IndexWriterConfig iwc = NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random()));
+ // Don't allow tiny maxBufferedDocs; it can make this
+ // test too slow:
+ iwc.SetMaxBufferedDocs(Math.Max(500, iwc.MaxBufferedDocs));
+
+ // MockRandom/AlcololicMergePolicy are too slow:
+ TieredMergePolicy tmp = new TieredMergePolicy();
+ tmp.FloorSegmentMB = .001;
+ iwc.SetMergePolicy(tmp);
+ IndexWriter w = new IndexWriter(dir, iwc);
+ var tw = new DirectoryTaxonomyWriter(taxoDir);
+ FacetsConfig config = new FacetsConfig();
+ config.SetMultiValued("field", true);
+ AtomicBoolean stop = new AtomicBoolean();
+
+ // How many unique facets to index before stopping:
+ int ordLimit = TEST_NIGHTLY ? 100000 : 6000;
+
+ var indexer = new IndexerThread(w, config, tw, null, ordLimit, stop);
+
+ var mgr = new SearcherTaxonomyManager(w, true, null, tw);
+
+ var reopener = new ThreadAnonymousInnerClassHelper(this, stop, mgr);
+
+ reopener.Name = "reopener";
+ reopener.Start();
+
+ indexer.Name = "indexer";
+ 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.IndexReader.NumDocs > 0)
+ {
+ //System.out.println(pair.taxonomyReader.getSize());
+ Assert.True(result.ChildCount > 0);
+ Assert.True(result.LabelValues.Length > 0);
+ }
+
+ //if (VERBOSE) {
+ //System.out.println("TEST: facets=" + FacetTestUtils.toString(results.get(0)));
+ //}
+ }
+ finally
+ {
+ mgr.Release(pair);
+ }
+ }
+ }
+ finally
+ {
+ indexer.Join();
+ reopener.Join();
+ }
+
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: now stop");
+ }
+
+ IOUtils.Close(mgr, tw, w, taxoDir, dir);
+ }
+
+ private class ThreadAnonymousInnerClassHelper : ThreadClass
+ {
+ private readonly TestSearcherTaxonomyManager outerInstance;
+
+ private AtomicBoolean stop;
+ private Lucene.Net.Facet.Taxonomy.SearcherTaxonomyManager mgr;
+
+ public ThreadAnonymousInnerClassHelper(TestSearcherTaxonomyManager outerInstance, AtomicBoolean stop, Lucene.Net.Facet.Taxonomy.SearcherTaxonomyManager mgr)
+ {
+ this.outerInstance = outerInstance;
+ this.stop = stop;
+ this.mgr = mgr;
+ }
+
+ public override void Run()
+ {
+ while (!stop.Get())
+ {
+ try
+ {
+ // Sleep for up to 20 msec:
+ Thread.Sleep(Random().Next(20));
+
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: reopen");
+ }
+
+ mgr.MaybeRefresh();
+
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: reopen done");
+ }
+ }
+ catch (Exception ioe)
+ {
+ throw new Exception(ioe.Message, ioe);
+ }
+ }
+ }
+ }
+
+
+ [Test]
+ public virtual void TestDirectory()
+ {
+ Store.Directory indexDir = NewDirectory();
+ Store.Directory taxoDir = NewDirectory();
+ IndexWriter w = new IndexWriter(indexDir, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())));
+ var tw = new DirectoryTaxonomyWriter(taxoDir);
+ // first empty commit
+ w.Commit();
+ tw.Commit();
+ var mgr = new SearcherTaxonomyManager(indexDir, taxoDir, null);
+ FacetsConfig config = new FacetsConfig();
+ config.SetMultiValued("field", true);
+ AtomicBoolean stop = new AtomicBoolean();
+
+ // How many unique facets to index before stopping:
+ int ordLimit = TEST_NIGHTLY ? 100000 : 6000;
+
+ var indexer = new IndexerThread(w, config, tw, mgr, ordLimit, stop);
+ 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.IndexReader.NumDocs > 0)
+ {
+ //System.out.println(pair.taxonomyReader.getSize());
+ Assert.True(result.ChildCount > 0);
+ Assert.True(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)
+ {
+ Console.WriteLine("TEST: now stop");
+ }
+
+ IOUtils.Close(mgr, tw, w, taxoDir, indexDir);
+ }
+
+ [Test]
+ public virtual void TestReplaceTaxonomyNrt()
+ {
+ Store.Directory dir = NewDirectory();
+ Store.Directory taxoDir = NewDirectory();
+ IndexWriter w = new IndexWriter(dir, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())));
+ var tw = new DirectoryTaxonomyWriter(taxoDir);
+
+ Store.Directory taxoDir2 = NewDirectory();
+ var tw2 = new DirectoryTaxonomyWriter(taxoDir2);
+ tw2.Dispose();
+
+ var mgr = new SearcherTaxonomyManager(w, true, null, tw);
+ w.AddDocument(new Document());
+ tw.ReplaceTaxonomy(taxoDir2);
+ taxoDir2.Dispose();
+
+ try
+ {
+ mgr.MaybeRefresh();
+ Fail("should have hit exception");
+ }
+ catch (IllegalStateException)
+ {
+ // expected
+ }
+
+ IOUtils.Close(mgr, tw, w, taxoDir, dir);
+ }
+
+ [Test]
+ public virtual void TestReplaceTaxonomyDirectory()
+ {
+ Store.Directory indexDir = NewDirectory();
+ Store.Directory taxoDir = NewDirectory();
+ IndexWriter w = new IndexWriter(indexDir, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())));
+ var tw = new DirectoryTaxonomyWriter(taxoDir);
+ w.Commit();
+ tw.Commit();
+
+ Store.Directory taxoDir2 = NewDirectory();
+ var tw2 = new DirectoryTaxonomyWriter(taxoDir2);
+ tw2.AddCategory(new FacetLabel("a", "b"));
+ tw2.Dispose();
+
+ var mgr = new SearcherTaxonomyManager(indexDir, taxoDir, null);
+ SearcherAndTaxonomy pair = mgr.Acquire();
+ try
+ {
+ Assert.AreEqual(1, pair.taxonomyReader.Size);
+ }
+ finally
+ {
+ mgr.Release(pair);
+ }
+
+ w.AddDocument(new Document());
+ tw.ReplaceTaxonomy(taxoDir2);
+ taxoDir2.Dispose();
+ w.Commit();
+ tw.Commit();
+
+ mgr.MaybeRefresh();
+ pair = mgr.Acquire();
+ try
+ {
+ Assert.AreEqual(3, pair.taxonomyReader.Size);
+ }
+ finally
+ {
+ mgr.Release(pair);
+ }
+
+ IOUtils.Close(mgr, tw, w, taxoDir, indexDir);
+ }
+
+ }
+
+}
\ No newline at end of file