You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2017/02/26 23:37:12 UTC
[24/72] [abbrv] [partial] lucenenet git commit: Lucene.Net.Tests:
Removed \core directory and put its contents in root directory
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Index/TestMultiFields.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Index/TestMultiFields.cs b/src/Lucene.Net.Tests/Index/TestMultiFields.cs
new file mode 100644
index 0000000..0d70862
--- /dev/null
+++ b/src/Lucene.Net.Tests/Index/TestMultiFields.cs
@@ -0,0 +1,228 @@
+using Lucene.Net.Documents;
+using Lucene.Net.Randomized.Generators;
+using System;
+using System.Collections.Generic;
+
+namespace Lucene.Net.Index
+{
+ using Lucene.Net.Analysis;
+
+ using Lucene.Net.Store;
+ using Lucene.Net.Util;
+ using NUnit.Framework;
+
+ /*
+ * 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 DocIdSetIterator = Lucene.Net.Search.DocIdSetIterator;
+
+ [TestFixture]
+ public class TestMultiFields : LuceneTestCase
+ {
+ [Test]
+ public virtual void TestRandom()
+ {
+ int num = AtLeast(2);
+ for (int iter = 0; iter < num; iter++)
+ {
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: iter=" + iter);
+ }
+
+ Directory dir = NewDirectory();
+
+ IndexWriter w = new IndexWriter(dir, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())).SetMergePolicy(NoMergePolicy.COMPOUND_FILES));
+ // we can do this because we use NoMergePolicy (and dont merge to "nothing")
+ w.KeepFullyDeletedSegments = true;
+
+ IDictionary<BytesRef, IList<int?>> docs = new Dictionary<BytesRef, IList<int?>>();
+ HashSet<int?> deleted = new HashSet<int?>();
+ IList<BytesRef> terms = new List<BytesRef>();
+
+ int numDocs = TestUtil.NextInt(Random(), 1, 100 * RANDOM_MULTIPLIER);
+ Documents.Document doc = new Documents.Document();
+ Field f = NewStringField("field", "", Field.Store.NO);
+ doc.Add(f);
+ Field id = NewStringField("id", "", Field.Store.NO);
+ doc.Add(id);
+
+ bool onlyUniqueTerms = Random().NextBoolean();
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: onlyUniqueTerms=" + onlyUniqueTerms + " numDocs=" + numDocs);
+ }
+ HashSet<BytesRef> uniqueTerms = new HashSet<BytesRef>();
+ for (int i = 0; i < numDocs; i++)
+ {
+ if (!onlyUniqueTerms && Random().NextBoolean() && terms.Count > 0)
+ {
+ // re-use existing term
+ BytesRef term = terms[Random().Next(terms.Count)];
+ docs[term].Add(i);
+ f.SetStringValue(term.Utf8ToString());
+ }
+ else
+ {
+ string s = TestUtil.RandomUnicodeString(Random(), 10);
+ BytesRef term = new BytesRef(s);
+ if (!docs.ContainsKey(term))
+ {
+ docs[term] = new List<int?>();
+ }
+ docs[term].Add(i);
+ terms.Add(term);
+ uniqueTerms.Add(term);
+ f.SetStringValue(s);
+ }
+ id.SetStringValue("" + i);
+ w.AddDocument(doc);
+ if (Random().Next(4) == 1)
+ {
+ w.Commit();
+ }
+ if (i > 0 && Random().Next(20) == 1)
+ {
+ int delID = Random().Next(i);
+ deleted.Add(delID);
+ w.DeleteDocuments(new Term("id", "" + delID));
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: delete " + delID);
+ }
+ }
+ }
+
+ if (VERBOSE)
+ {
+ List<BytesRef> termsList = new List<BytesRef>(uniqueTerms);
+#pragma warning disable 612, 618
+ termsList.Sort(BytesRef.UTF8SortedAsUTF16Comparer);
+#pragma warning restore 612, 618
+ Console.WriteLine("TEST: terms in UTF16 order:");
+ foreach (BytesRef b in termsList)
+ {
+ Console.WriteLine(" " + UnicodeUtil.ToHexString(b.Utf8ToString()) + " " + b);
+ foreach (int docID in docs[b])
+ {
+ if (deleted.Contains(docID))
+ {
+ Console.WriteLine(" " + docID + " (deleted)");
+ }
+ else
+ {
+ Console.WriteLine(" " + docID);
+ }
+ }
+ }
+ }
+
+ IndexReader reader = w.Reader;
+ w.Dispose();
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: reader=" + reader);
+ }
+
+ IBits liveDocs = MultiFields.GetLiveDocs(reader);
+ foreach (int delDoc in deleted)
+ {
+ Assert.IsFalse(liveDocs.Get(delDoc));
+ }
+
+ for (int i = 0; i < 100; i++)
+ {
+ BytesRef term = terms[Random().Next(terms.Count)];
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: seek term=" + UnicodeUtil.ToHexString(term.Utf8ToString()) + " " + term);
+ }
+
+ DocsEnum docsEnum = TestUtil.Docs(Random(), reader, "field", term, liveDocs, null, DocsEnum.FLAG_NONE);
+ Assert.IsNotNull(docsEnum);
+
+ foreach (int docID in docs[term])
+ {
+ if (!deleted.Contains(docID))
+ {
+ Assert.AreEqual(docID, docsEnum.NextDoc());
+ }
+ }
+ Assert.AreEqual(DocIdSetIterator.NO_MORE_DOCS, docsEnum.NextDoc());
+ }
+
+ reader.Dispose();
+ dir.Dispose();
+ }
+ }
+
+ /*
+ private void verify(IndexReader r, String term, List<Integer> expected) throws Exception {
+ DocsEnum docs = TestUtil.Docs(random, r,
+ "field",
+ new BytesRef(term),
+ MultiFields.GetLiveDocs(r),
+ null,
+ false);
+ for(int docID : expected) {
+ Assert.AreEqual(docID, docs.NextDoc());
+ }
+ Assert.AreEqual(docs.NO_MORE_DOCS, docs.NextDoc());
+ }
+ */
+
+ [Test]
+ public virtual void TestSeparateEnums()
+ {
+ Directory dir = NewDirectory();
+ IndexWriter w = new IndexWriter(dir, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())));
+ Documents.Document d = new Documents.Document();
+ d.Add(NewStringField("f", "j", Field.Store.NO));
+ w.AddDocument(d);
+ w.Commit();
+ w.AddDocument(d);
+ IndexReader r = w.Reader;
+ w.Dispose();
+ DocsEnum d1 = TestUtil.Docs(Random(), r, "f", new BytesRef("j"), null, null, DocsEnum.FLAG_NONE);
+ DocsEnum d2 = TestUtil.Docs(Random(), r, "f", new BytesRef("j"), null, null, DocsEnum.FLAG_NONE);
+ Assert.AreEqual(0, d1.NextDoc());
+ Assert.AreEqual(0, d2.NextDoc());
+ r.Dispose();
+ dir.Dispose();
+ }
+
+ [Test]
+ public virtual void TestTermDocsEnum()
+ {
+ Directory dir = NewDirectory();
+ IndexWriter w = new IndexWriter(dir, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())));
+ Documents.Document d = new Documents.Document();
+ d.Add(NewStringField("f", "j", Field.Store.NO));
+ w.AddDocument(d);
+ w.Commit();
+ w.AddDocument(d);
+ IndexReader r = w.Reader;
+ w.Dispose();
+ DocsEnum de = MultiFields.GetTermDocsEnum(r, null, "f", new BytesRef("j"));
+ Assert.AreEqual(0, de.NextDoc());
+ Assert.AreEqual(1, de.NextDoc());
+ Assert.AreEqual(DocIdSetIterator.NO_MORE_DOCS, de.NextDoc());
+ r.Dispose();
+ dir.Dispose();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Index/TestMultiLevelSkipList.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Index/TestMultiLevelSkipList.cs b/src/Lucene.Net.Tests/Index/TestMultiLevelSkipList.cs
new file mode 100644
index 0000000..49456ed
--- /dev/null
+++ b/src/Lucene.Net.Tests/Index/TestMultiLevelSkipList.cs
@@ -0,0 +1,218 @@
+using Lucene.Net.Analysis.TokenAttributes;
+using Lucene.Net.Documents;
+
+namespace Lucene.Net.Index
+{
+ /*
+ * 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.Analysis;
+ using Lucene.Net.Support;
+ using NUnit.Framework;
+ using System.IO;
+ using BytesRef = Lucene.Net.Util.BytesRef;
+ using Directory = Lucene.Net.Store.Directory;
+ using Document = Documents.Document;
+ using Field = Field;
+ using IndexInput = Lucene.Net.Store.IndexInput;
+ using IOContext = Lucene.Net.Store.IOContext;
+ using Lucene41PostingsFormat = Lucene.Net.Codecs.Lucene41.Lucene41PostingsFormat;
+ using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+ using MockDirectoryWrapper = Lucene.Net.Store.MockDirectoryWrapper;
+ using RAMDirectory = Lucene.Net.Store.RAMDirectory;
+ using TestUtil = Lucene.Net.Util.TestUtil;
+
+ /// <summary>
+ /// this testcase tests whether multi-level skipping is being used
+ /// to reduce I/O while skipping through posting lists.
+ ///
+ /// Skipping in general is already covered by several other
+ /// testcases.
+ ///
+ /// </summary>
+ [TestFixture]
+ public class TestMultiLevelSkipList : LuceneTestCase
+ {
+ internal class CountingRAMDirectory : MockDirectoryWrapper
+ {
+ private readonly TestMultiLevelSkipList OuterInstance;
+
+ public CountingRAMDirectory(TestMultiLevelSkipList outerInstance, Directory @delegate)
+ : base(Random(), @delegate)
+ {
+ this.OuterInstance = outerInstance;
+ }
+
+ public override IndexInput OpenInput(string fileName, IOContext context)
+ {
+ IndexInput @in = base.OpenInput(fileName, context);
+ if (fileName.EndsWith(".frq"))
+ {
+ @in = new CountingStream(OuterInstance, @in);
+ }
+ return @in;
+ }
+ }
+
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ Counter = 0;
+ }
+
+ [Test]
+ public virtual void TestSimpleSkip()
+ {
+ Directory dir = new CountingRAMDirectory(this, new RAMDirectory());
+ IndexWriter writer = new IndexWriter(dir, NewIndexWriterConfig(TEST_VERSION_CURRENT, new PayloadAnalyzer()).SetCodec(TestUtil.AlwaysPostingsFormat(new Lucene41PostingsFormat())).SetMergePolicy(NewLogMergePolicy()));
+ Term term = new Term("test", "a");
+ for (int i = 0; i < 5000; i++)
+ {
+ Document d1 = new Document();
+ d1.Add(NewTextField(term.Field, term.Text(), Field.Store.NO));
+ writer.AddDocument(d1);
+ }
+ writer.Commit();
+ writer.ForceMerge(1);
+ writer.Dispose();
+
+ AtomicReader reader = GetOnlySegmentReader(DirectoryReader.Open(dir));
+
+ for (int i = 0; i < 2; i++)
+ {
+ Counter = 0;
+ DocsAndPositionsEnum tp = reader.TermPositionsEnum(term);
+ CheckSkipTo(tp, 14, 185); // no skips
+ CheckSkipTo(tp, 17, 190); // one skip on level 0
+ CheckSkipTo(tp, 287, 200); // one skip on level 1, two on level 0
+
+ // this test would fail if we had only one skip level,
+ // because than more bytes would be read from the freqStream
+ CheckSkipTo(tp, 4800, 250); // one skip on level 2
+ }
+ }
+
+ public virtual void CheckSkipTo(DocsAndPositionsEnum tp, int target, int maxCounter)
+ {
+ tp.Advance(target);
+ if (maxCounter < Counter)
+ {
+ Assert.Fail("Too many bytes read: " + Counter + " vs " + maxCounter);
+ }
+
+ Assert.AreEqual(target, tp.DocID, "Wrong document " + tp.DocID + " after skipTo target " + target);
+ Assert.AreEqual(1, tp.Freq, "Frequency is not 1: " + tp.Freq);
+ tp.NextPosition();
+ BytesRef b = tp.GetPayload();
+ Assert.AreEqual(1, b.Length);
+ Assert.AreEqual((sbyte)target, (sbyte)b.Bytes[b.Offset], "Wrong payload for the target " + target + ": " + (sbyte)b.Bytes[b.Offset]);
+ }
+
+ private class PayloadAnalyzer : Analyzer
+ {
+ internal readonly AtomicInt32 PayloadCount = new AtomicInt32(-1);
+
+ protected internal override TokenStreamComponents CreateComponents(string fieldName, TextReader reader)
+ {
+ Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, true);
+ return new TokenStreamComponents(tokenizer, new PayloadFilter(PayloadCount, tokenizer));
+ }
+ }
+
+ private class PayloadFilter : TokenFilter
+ {
+ internal IPayloadAttribute PayloadAtt;
+ internal AtomicInt32 PayloadCount;
+
+ protected internal PayloadFilter(AtomicInt32 payloadCount, TokenStream input)
+ : base(input)
+ {
+ this.PayloadCount = payloadCount;
+ PayloadAtt = AddAttribute<IPayloadAttribute>();
+ }
+
+ public sealed override bool IncrementToken()
+ {
+ bool hasNext = m_input.IncrementToken();
+ if (hasNext)
+ {
+ PayloadAtt.Payload = new BytesRef(new[] { (byte)PayloadCount.IncrementAndGet() });
+ }
+ return hasNext;
+ }
+ }
+
+ private int Counter = 0;
+
+ // Simply extends IndexInput in a way that we are able to count the number
+ // of bytes read
+ internal class CountingStream : IndexInput
+ {
+ private readonly TestMultiLevelSkipList OuterInstance;
+
+ internal IndexInput Input;
+
+ internal CountingStream(TestMultiLevelSkipList outerInstance, IndexInput input)
+ : base("CountingStream(" + input + ")")
+ {
+ this.OuterInstance = outerInstance;
+ this.Input = input;
+ }
+
+ public override byte ReadByte()
+ {
+ OuterInstance.Counter++;
+ return this.Input.ReadByte();
+ }
+
+ public override void ReadBytes(byte[] b, int offset, int len)
+ {
+ OuterInstance.Counter += len;
+ this.Input.ReadBytes(b, offset, len);
+ }
+
+ public override void Dispose()
+ {
+ this.Input.Dispose();
+ }
+
+ public override long FilePointer
+ {
+ get
+ {
+ return this.Input.FilePointer;
+ }
+ }
+
+ public override void Seek(long pos)
+ {
+ this.Input.Seek(pos);
+ }
+
+ public override long Length
+ {
+ get { return this.Input.Length; }
+ }
+
+ public override object Clone()
+ {
+ return new CountingStream(OuterInstance, (IndexInput)this.Input.Clone());
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs b/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs
new file mode 100644
index 0000000..918b5b5
--- /dev/null
+++ b/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs
@@ -0,0 +1,140 @@
+using System;
+using System.Threading;
+
+namespace Lucene.Net.Index
+{
+ using Lucene.Net.Support;
+ using NUnit.Framework;
+ using Directory = Lucene.Net.Store.Directory;
+ using Document = Documents.Document;
+ using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+ /*
+ * 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 MockDirectoryWrapper = Lucene.Net.Store.MockDirectoryWrapper;
+
+ [TestFixture]
+ public class TestNRTReaderWithThreads : LuceneTestCase
+ {
+ internal AtomicInt32 Seq = new AtomicInt32(1);
+ [Test]
+ public virtual void TestIndexing()
+ {
+ Directory mainDir = NewDirectory();
+ var wrapper = mainDir as MockDirectoryWrapper;
+ if (wrapper != null)
+ {
+ wrapper.AssertNoDeleteOpenFile = true;
+ }
+ var writer = new IndexWriter(mainDir, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())).SetMaxBufferedDocs(10).SetMergePolicy(NewLogMergePolicy(false, 2)));
+ IndexReader reader = writer.Reader; // start pooling readers
+ reader.Dispose();
+ var indexThreads = new RunThread[4];
+ for (int x = 0; x < indexThreads.Length; x++)
+ {
+ indexThreads[x] = new RunThread(this, x % 2, writer);
+ indexThreads[x].Name = "Thread " + x;
+ indexThreads[x].Start();
+ }
+ long startTime = Environment.TickCount;
+ long duration = 1000;
+ while ((Environment.TickCount - startTime) < duration)
+ {
+ Thread.Sleep(100);
+ }
+ int delCount = 0;
+ int addCount = 0;
+ for (int x = 0; x < indexThreads.Length; x++)
+ {
+ indexThreads[x].Run_Renamed = false;
+ Assert.IsNull(indexThreads[x].Ex, "Exception thrown: " + indexThreads[x].Ex);
+ addCount += indexThreads[x].AddCount;
+ delCount += indexThreads[x].DelCount;
+ }
+ for (int x = 0; x < indexThreads.Length; x++)
+ {
+ indexThreads[x].Join();
+ }
+ for (int x = 0; x < indexThreads.Length; x++)
+ {
+ Assert.IsNull(indexThreads[x].Ex, "Exception thrown: " + indexThreads[x].Ex);
+ }
+ //System.out.println("addCount:"+addCount);
+ //System.out.println("delCount:"+delCount);
+ writer.Dispose();
+ mainDir.Dispose();
+ }
+
+ public class RunThread : ThreadClass
+ {
+ private readonly TestNRTReaderWithThreads OuterInstance;
+
+ internal IndexWriter Writer;
+ internal volatile bool Run_Renamed = true;
+ internal volatile Exception Ex;
+ internal int DelCount = 0;
+ internal int AddCount = 0;
+ internal int Type;
+ internal readonly Random r = new Random(Random().Next());
+
+ public RunThread(TestNRTReaderWithThreads outerInstance, int type, IndexWriter writer)
+ {
+ this.OuterInstance = outerInstance;
+ this.Type = type;
+ this.Writer = writer;
+ }
+
+ public override void Run()
+ {
+ try
+ {
+ while (Run_Renamed)
+ {
+ //int n = random.nextInt(2);
+ if (Type == 0)
+ {
+ int i = OuterInstance.Seq.AddAndGet(1);
+ Document doc = DocHelper.CreateDocument(i, "index1", 10);
+ Writer.AddDocument(doc);
+ AddCount++;
+ }
+ else if (Type == 1)
+ {
+ // we may or may not delete because the term may not exist,
+ // however we're opening and closing the reader rapidly
+ IndexReader reader = Writer.Reader;
+ int id = r.Next(OuterInstance.Seq.Get());
+ Term term = new Term("id", Convert.ToString(id));
+ int count = TestIndexWriterReader.Count(term, reader);
+ Writer.DeleteDocuments(term);
+ reader.Dispose();
+ DelCount += count;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.StackTrace);
+ this.Ex = ex;
+ Run_Renamed = false;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Index/TestNRTThreads.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Index/TestNRTThreads.cs b/src/Lucene.Net.Tests/Index/TestNRTThreads.cs
new file mode 100644
index 0000000..f6815cb
--- /dev/null
+++ b/src/Lucene.Net.Tests/Index/TestNRTThreads.cs
@@ -0,0 +1,185 @@
+using System;
+using System.Diagnostics;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.Index
+{
+ using Lucene.Net.Randomized.Generators;
+ using NUnit.Framework;
+ using System.Collections.Generic;
+ using Directory = Lucene.Net.Store.Directory;
+
+ /*
+ * 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 IndexSearcher = Lucene.Net.Search.IndexSearcher;
+ using MockDirectoryWrapper = Lucene.Net.Store.MockDirectoryWrapper;
+
+ // TODO
+ // - mix in forceMerge, addIndexes
+ // - randomoly mix in non-congruent docs
+ [SuppressCodecs("SimpleText", "Memory", "Direct")]
+ [TestFixture]
+ public class TestNRTThreads : ThreadedIndexingAndSearchingTestCase
+ {
+ private bool UseNonNrtReaders = true;
+
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+ UseNonNrtReaders = Random().NextBoolean();
+ }
+
+ protected internal override void DoSearching(TaskScheduler es, DateTime stopTime)
+ {
+ bool anyOpenDelFiles = false;
+
+ DirectoryReader r = DirectoryReader.Open(Writer, true);
+
+ while (DateTime.UtcNow < stopTime && !Failed.Get())
+ {
+ if (Random().NextBoolean())
+ {
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: now reopen r=" + r);
+ }
+ DirectoryReader r2 = DirectoryReader.OpenIfChanged(r);
+ if (r2 != null)
+ {
+ r.Dispose();
+ r = r2;
+ }
+ }
+ else
+ {
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: now close reader=" + r);
+ }
+ r.Dispose();
+ Writer.Commit();
+ ISet<string> openDeletedFiles = ((MockDirectoryWrapper)Dir).OpenDeletedFiles;
+ if (openDeletedFiles.Count > 0)
+ {
+ Console.WriteLine("OBD files: " + openDeletedFiles);
+ }
+ anyOpenDelFiles |= openDeletedFiles.Count > 0;
+ //Assert.AreEqual("open but deleted: " + openDeletedFiles, 0, openDeletedFiles.Size());
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: now open");
+ }
+ r = DirectoryReader.Open(Writer, true);
+ }
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: got new reader=" + r);
+ }
+ //System.out.println("numDocs=" + r.NumDocs + "
+ //openDelFileCount=" + dir.openDeleteFileCount());
+
+ if (r.NumDocs > 0)
+ {
+ FixedSearcher = new IndexSearcher(r, es);
+ SmokeTestSearcher(FixedSearcher);
+ RunSearchThreads(DateTime.UtcNow.AddMilliseconds(500));
+ }
+ }
+ r.Dispose();
+
+ //System.out.println("numDocs=" + r.NumDocs + " openDelFileCount=" + dir.openDeleteFileCount());
+ ISet<string> openDeletedFiles_ = ((MockDirectoryWrapper)Dir).OpenDeletedFiles;
+ if (openDeletedFiles_.Count > 0)
+ {
+ Console.WriteLine("OBD files: " + openDeletedFiles_);
+ }
+ anyOpenDelFiles |= openDeletedFiles_.Count > 0;
+
+ Assert.IsFalse(anyOpenDelFiles, "saw non-zero open-but-deleted count");
+ }
+
+ protected internal override Directory GetDirectory(Directory @in)
+ {
+ Debug.Assert(@in is MockDirectoryWrapper);
+ if (!UseNonNrtReaders)
+ {
+ ((MockDirectoryWrapper)@in).AssertNoDeleteOpenFile = true;
+ }
+ return @in;
+ }
+
+ protected internal override void DoAfterWriter(TaskScheduler es)
+ {
+ // Force writer to do reader pooling, always, so that
+ // all merged segments, even for merges before
+ // doSearching is called, are warmed:
+ Writer.Reader.Dispose();
+ }
+
+ private IndexSearcher FixedSearcher;
+
+ protected internal override IndexSearcher CurrentSearcher
+ {
+ get
+ {
+ return FixedSearcher;
+ }
+ }
+
+ protected internal override void ReleaseSearcher(IndexSearcher s)
+ {
+ if (s != FixedSearcher)
+ {
+ // Final searcher:
+ s.IndexReader.Dispose();
+ }
+ }
+
+ protected internal override IndexSearcher FinalSearcher
+ {
+ get
+ {
+ IndexReader r2;
+ if (UseNonNrtReaders)
+ {
+ if (Random().NextBoolean())
+ {
+ r2 = Writer.Reader;
+ }
+ else
+ {
+ Writer.Commit();
+ r2 = DirectoryReader.Open(Dir);
+ }
+ }
+ else
+ {
+ r2 = Writer.Reader;
+ }
+ return NewSearcher(r2);
+ }
+ }
+
+ [Test]
+ public virtual void TestNRTThreads_Mem()
+ {
+ RunTest("TestNRTThreads");
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Index/TestNeverDelete.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Index/TestNeverDelete.cs b/src/Lucene.Net.Tests/Index/TestNeverDelete.cs
new file mode 100644
index 0000000..572182c
--- /dev/null
+++ b/src/Lucene.Net.Tests/Index/TestNeverDelete.cs
@@ -0,0 +1,158 @@
+using Lucene.Net.Documents;
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+
+namespace Lucene.Net.Index
+{
+ using Lucene.Net.Support;
+ using BaseDirectoryWrapper = Lucene.Net.Store.BaseDirectoryWrapper;
+ using Document = Documents.Document;
+ using Field = Field;
+ using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+ /*
+ * 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 MockDirectoryWrapper = Lucene.Net.Store.MockDirectoryWrapper;
+ using TestUtil = Lucene.Net.Util.TestUtil;
+
+ // Make sure if you use NoDeletionPolicy that no file
+ // referenced by a commit point is ever deleted
+
+ [TestFixture]
+ public class TestNeverDelete : LuceneTestCase
+ {
+ [Test]
+ public virtual void TestIndexing()
+ {
+ DirectoryInfo tmpDir = CreateTempDir("TestNeverDelete");
+ BaseDirectoryWrapper d = NewFSDirectory(tmpDir);
+
+ // We want to "see" files removed if Lucene removed
+ // them. this is still worth running on Windows since
+ // some files the IR opens and closes.
+ if (d is MockDirectoryWrapper)
+ {
+ ((MockDirectoryWrapper)d).NoDeleteOpenFile = false;
+ }
+ RandomIndexWriter w = new RandomIndexWriter(Random(), d, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())).SetIndexDeletionPolicy(NoDeletionPolicy.INSTANCE));
+ w.w.Config.SetMaxBufferedDocs(TestUtil.NextInt(Random(), 5, 30));
+
+ w.Commit();
+ ThreadClass[] indexThreads = new ThreadClass[Random().Next(4)];
+ long stopTime = Environment.TickCount + AtLeast(1000);
+ for (int x = 0; x < indexThreads.Length; x++)
+ {
+ indexThreads[x] = new ThreadAnonymousInnerClassHelper(w, stopTime, NewStringField, NewTextField);
+ indexThreads[x].Name = "Thread " + x;
+ indexThreads[x].Start();
+ }
+
+ HashSet<string> allFiles = new HashSet<string>();
+
+ DirectoryReader r = DirectoryReader.Open(d);
+ while (Environment.TickCount < stopTime)
+ {
+ IndexCommit ic = r.IndexCommit;
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: check files: " + ic.FileNames);
+ }
+ allFiles.AddAll(ic.FileNames);
+ // Make sure no old files were removed
+ foreach (string fileName in allFiles)
+ {
+ Assert.IsTrue(SlowFileExists(d, fileName), "file " + fileName + " does not exist");
+ }
+ DirectoryReader r2 = DirectoryReader.OpenIfChanged(r);
+ if (r2 != null)
+ {
+ r.Dispose();
+ r = r2;
+ }
+ Thread.Sleep(1);
+ }
+ r.Dispose();
+
+ foreach (ThreadClass t in indexThreads)
+ {
+ t.Join();
+ }
+ w.Dispose();
+ d.Dispose();
+
+ System.IO.Directory.Delete(tmpDir.FullName, true);
+ }
+
+ private class ThreadAnonymousInnerClassHelper : ThreadClass
+ {
+ private readonly Func<string, string, Field.Store, Field> NewStringField;
+ private readonly Func<string, string, Field.Store, Field> NewTextField;
+
+ private RandomIndexWriter w;
+ private long StopTime;
+
+ /// <param name="newStringField">
+ /// LUCENENET specific
+ /// Passed in because <see cref="LuceneTestCase.NewStringField(string, string, Field.Store)"/>
+ /// is no longer static
+ /// </param>
+ /// <param name="newTextField">
+ /// LUCENENET specific
+ /// Passed in because <see cref="LuceneTestCase.NewTextField(string, string, Field.Store)"/>
+ /// is no longer static
+ /// </param>
+ public ThreadAnonymousInnerClassHelper(RandomIndexWriter w, long stopTime,
+ Func<string, string, Field.Store, Field> newStringField, Func<string, string, Field.Store, Field> newTextField)
+ {
+ this.w = w;
+ this.StopTime = stopTime;
+ NewStringField = newStringField;
+ NewTextField = newTextField;
+ }
+
+ public override void Run()
+ {
+ try
+ {
+ int docCount = 0;
+ while (Environment.TickCount < StopTime)
+ {
+ Document doc = new Document();
+ doc.Add(NewStringField("dc", "" + docCount, Field.Store.YES));
+ doc.Add(NewTextField("field", "here is some text", Field.Store.YES));
+ w.AddDocument(doc);
+
+ if (docCount % 13 == 0)
+ {
+ w.Commit();
+ }
+ docCount++;
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception(e.Message, e);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Index/TestNewestSegment.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Index/TestNewestSegment.cs b/src/Lucene.Net.Tests/Index/TestNewestSegment.cs
new file mode 100644
index 0000000..fc76173
--- /dev/null
+++ b/src/Lucene.Net.Tests/Index/TestNewestSegment.cs
@@ -0,0 +1,39 @@
+namespace Lucene.Net.Index
+{
+ using NUnit.Framework;
+ using Directory = Lucene.Net.Store.Directory;
+ using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+ /*
+ * 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;
+
+ [TestFixture]
+ public class TestNewestSegment : LuceneTestCase
+ {
+ [Test]
+ public virtual void TestNewestSegment_Mem()
+ {
+ Directory directory = NewDirectory();
+ IndexWriter writer = new IndexWriter(directory, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())));
+ Assert.IsNull(writer.NewestSegment());
+ writer.Dispose();
+ directory.Dispose();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Index/TestNoDeletionPolicy.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Index/TestNoDeletionPolicy.cs b/src/Lucene.Net.Tests/Index/TestNoDeletionPolicy.cs
new file mode 100644
index 0000000..a91b485
--- /dev/null
+++ b/src/Lucene.Net.Tests/Index/TestNoDeletionPolicy.cs
@@ -0,0 +1,95 @@
+using System.Reflection;
+using Lucene.Net.Documents;
+
+namespace Lucene.Net.Index
+{
+ using NUnit.Framework;
+ using Support;
+ using Directory = Lucene.Net.Store.Directory;
+ using Document = Documents.Document;
+ using Field = Field;
+ using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+ /*
+ * 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;
+
+ [TestFixture]
+ public class TestNoDeletionPolicy : LuceneTestCase
+ {
+ [Test]
+ public virtual void TestNoDeletionPolicy_Mem()
+ {
+ IndexDeletionPolicy idp = NoDeletionPolicy.INSTANCE;
+ idp.OnInit<IndexCommit>(null);
+ idp.OnCommit<IndexCommit>(null);
+ }
+
+ [Test]
+ public virtual void TestFinalSingleton()
+ {
+ assertTrue(typeof(NoDeletionPolicy).GetTypeInfo().IsSealed);
+ ConstructorInfo[] ctors = typeof(NoDeletionPolicy).GetConstructors(BindingFlags.Instance |
+ BindingFlags.NonPublic |
+ BindingFlags.Public |
+ BindingFlags.DeclaredOnly); // LUCENENET NOTE: It seems .NET automatically adds a private static constructor, so leaving off the static BindingFlag
+ assertEquals("expected 1 private ctor only: " + Arrays.ToString(ctors), 1, ctors.Length);
+ assertTrue("that 1 should be private: " + ctors[0], ctors[0].IsPrivate);
+ }
+
+ [Test]
+ public virtual void TestMethodsOverridden()
+ {
+ // Ensures that all methods of IndexDeletionPolicy are
+ // overridden/implemented. That's important to ensure that NoDeletionPolicy
+ // overrides everything, so that no unexpected behavior/error occurs.
+ // NOTE: even though IndexDeletionPolicy is an interface today, and so all
+ // methods must be implemented by NoDeletionPolicy, this test is important
+ // in case one day IDP becomes an abstract class.
+ foreach (MethodInfo m in typeof(NoDeletionPolicy).GetMethods())
+ {
+ // getDeclaredMethods() returns just those methods that are declared on
+ // NoDeletionPolicy. getMethods() returns those that are visible in that
+ // context, including ones from Object. So just filter out Object. If in
+ // the future IndexDeletionPolicy will become a class that extends a
+ // different class than Object, this will need to change.
+ if (m.DeclaringType != typeof(object) && !m.IsFinal && m.IsVirtual)
+ {
+ Assert.IsTrue(m.DeclaringType == typeof(NoDeletionPolicy), m + " is not overridden !");
+ }
+ }
+ }
+
+ [Test]
+ public virtual void TestAllCommitsRemain()
+ {
+ Directory dir = NewDirectory();
+ IndexWriter writer = new IndexWriter(dir, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())).SetIndexDeletionPolicy(NoDeletionPolicy.INSTANCE));
+ for (int i = 0; i < 10; i++)
+ {
+ Document doc = new Document();
+ doc.Add(NewTextField("c", "a" + i, Field.Store.YES));
+ writer.AddDocument(doc);
+ writer.Commit();
+ Assert.AreEqual(i + 1, DirectoryReader.ListCommits(dir).Count, "wrong number of commits !");
+ }
+ writer.Dispose();
+ dir.Dispose();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Index/TestNoMergePolicy.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Index/TestNoMergePolicy.cs b/src/Lucene.Net.Tests/Index/TestNoMergePolicy.cs
new file mode 100644
index 0000000..694126b
--- /dev/null
+++ b/src/Lucene.Net.Tests/Index/TestNoMergePolicy.cs
@@ -0,0 +1,83 @@
+using Lucene.Net.Support;
+using NUnit.Framework;
+using System.Reflection;
+
+namespace Lucene.Net.Index
+{
+ /*
+ * 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 LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+ [TestFixture]
+ public class TestNoMergePolicy : LuceneTestCase
+ {
+ [Test]
+ public virtual void TestNoMergePolicy_Mem()
+ {
+ MergePolicy mp = NoMergePolicy.NO_COMPOUND_FILES;
+ Assert.IsNull(mp.FindMerges(null, (SegmentInfos)null));
+ Assert.IsNull(mp.FindForcedMerges(null, 0, null));
+ Assert.IsNull(mp.FindForcedDeletesMerges(null));
+ Assert.IsFalse(mp.UseCompoundFile(null, null));
+ mp.Dispose();
+ }
+
+ [Test]
+ public virtual void TestCompoundFiles()
+ {
+ Assert.IsFalse(NoMergePolicy.NO_COMPOUND_FILES.UseCompoundFile(null, null));
+ Assert.IsTrue(NoMergePolicy.COMPOUND_FILES.UseCompoundFile(null, null));
+ }
+
+ [Test]
+ public virtual void TestFinalSingleton()
+ {
+ assertTrue(typeof(NoMergePolicy).GetTypeInfo().IsSealed);
+ ConstructorInfo[] ctors = typeof(NoMergePolicy).GetConstructors(BindingFlags.Instance |
+ BindingFlags.NonPublic |
+ BindingFlags.Public |
+ BindingFlags.DeclaredOnly); // LUCENENET NOTE: It seems .NET automatically adds a private static constructor, so leaving off the static BindingFlag
+ assertEquals("expected 1 private ctor only: " + Arrays.ToString(ctors), 1, ctors.Length);
+ assertTrue("that 1 should be private: " + ctors[0], ctors[0].IsPrivate);
+ }
+
+ [Test]
+ public virtual void TestMethodsOverridden()
+ {
+ // Ensures that all methods of MergePolicy are overridden. That's important
+ // to ensure that NoMergePolicy overrides everything, so that no unexpected
+ // behavior/error occurs
+ foreach (MethodInfo m in typeof(NoMergePolicy).GetMethods())
+ {
+ // getDeclaredMethods() returns just those methods that are declared on
+ // NoMergePolicy. getMethods() returns those that are visible in that
+ // context, including ones from Object. So just filter out Object. If in
+ // the future MergePolicy will extend a different class than Object, this
+ // will need to change.
+ if (m.Name.Equals("Clone"))
+ {
+ continue;
+ }
+ if (m.DeclaringType != typeof(object) && !m.IsFinal && m.IsVirtual)
+ {
+ Assert.IsTrue(m.DeclaringType == typeof(NoMergePolicy), m + " is not overridden ! Declaring Type: " + m.DeclaringType);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Index/TestNoMergeScheduler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Index/TestNoMergeScheduler.cs b/src/Lucene.Net.Tests/Index/TestNoMergeScheduler.cs
new file mode 100644
index 0000000..9e20f64
--- /dev/null
+++ b/src/Lucene.Net.Tests/Index/TestNoMergeScheduler.cs
@@ -0,0 +1,72 @@
+using Lucene.Net.Randomized.Generators;
+using Lucene.Net.Support;
+using NUnit.Framework;
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace Lucene.Net.Index
+{
+ /*
+ * 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 LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+ [TestFixture]
+ public class TestNoMergeScheduler : LuceneTestCase
+ {
+ [Test]
+ public virtual void TestNoMergeScheduler_Mem()
+ {
+ MergeScheduler ms = NoMergeScheduler.INSTANCE;
+ ms.Dispose();
+ ms.Merge(null, RandomInts.RandomFrom(Random(), Enum.GetValues(typeof(MergeTrigger)).Cast<MergeTrigger>().ToArray()), Random().NextBoolean());
+ }
+
+ [Test]
+ public virtual void TestFinalSingleton()
+ {
+ assertTrue(typeof(NoMergeScheduler).GetTypeInfo().IsSealed);
+ ConstructorInfo[] ctors = typeof(NoMergeScheduler).GetConstructors(BindingFlags.Instance |
+ BindingFlags.NonPublic |
+ BindingFlags.Public |
+ BindingFlags.DeclaredOnly); // LUCENENET NOTE: It seems .NET automatically adds a private static constructor, so leaving off the static BindingFlag
+ assertEquals("expected 1 private ctor only: " + Arrays.ToString(ctors), 1, ctors.Length);
+ assertTrue("that 1 should be private: " + ctors[0], ctors[0].IsPrivate);
+ }
+
+ [Test]
+ public virtual void TestMethodsOverridden()
+ {
+ // Ensures that all methods of MergeScheduler are overridden. That's
+ // important to ensure that NoMergeScheduler overrides everything, so that
+ // no unexpected behavior/error occurs
+ foreach (MethodInfo m in typeof(NoMergeScheduler).GetMethods())
+ {
+ // getDeclaredMethods() returns just those methods that are declared on
+ // NoMergeScheduler. getMethods() returns those that are visible in that
+ // context, including ones from Object. So just filter out Object. If in
+ // the future MergeScheduler will extend a different class than Object,
+ // this will need to change.
+ if (m.DeclaringType != typeof(object) && !m.IsFinal && m.IsVirtual)
+ {
+ Assert.IsTrue(m.DeclaringType == typeof(NoMergeScheduler), m + " is not overridden !");
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/96822396/src/Lucene.Net.Tests/Index/TestNorms.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Index/TestNorms.cs b/src/Lucene.Net.Tests/Index/TestNorms.cs
new file mode 100644
index 0000000..f6bcdcf
--- /dev/null
+++ b/src/Lucene.Net.Tests/Index/TestNorms.cs
@@ -0,0 +1,252 @@
+using System;
+using Lucene.Net.Documents;
+
+namespace Lucene.Net.Index
+{
+ using NUnit.Framework;
+ using BytesRef = Lucene.Net.Util.BytesRef;
+ using CollectionStatistics = Lucene.Net.Search.CollectionStatistics;
+ using DefaultSimilarity = Lucene.Net.Search.Similarities.DefaultSimilarity;
+ using Directory = Lucene.Net.Store.Directory;
+ using Document = Documents.Document;
+ using Field = Field;
+ using LineFileDocs = Lucene.Net.Util.LineFileDocs;
+
+ //using Slow = Lucene.Net.Util.LuceneTestCase.Slow;
+ using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+ /*
+ * 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 PerFieldSimilarityWrapper = Lucene.Net.Search.Similarities.PerFieldSimilarityWrapper;
+ using Similarity = Lucene.Net.Search.Similarities.Similarity;
+ using TermStatistics = Lucene.Net.Search.TermStatistics;
+ using TestUtil = Lucene.Net.Util.TestUtil;
+ using TextField = TextField;
+ using TFIDFSimilarity = Lucene.Net.Search.Similarities.TFIDFSimilarity;
+
+ /// <summary>
+ /// Test that norms info is preserved during index life - including
+ /// separate norms, addDocument, addIndexes, forceMerge.
+ /// </summary>
+ [SuppressCodecs("Memory", "Direct", "SimpleText")]
+ [TestFixture]
+ public class TestNorms : LuceneTestCase
+ {
+ internal readonly string ByteTestField = "normsTestByte";
+
+ internal class CustomNormEncodingSimilarity : TFIDFSimilarity
+ {
+ private readonly TestNorms OuterInstance;
+
+ public CustomNormEncodingSimilarity(TestNorms outerInstance)
+ {
+ this.OuterInstance = outerInstance;
+ }
+
+ public override long EncodeNormValue(float f)
+ {
+ return (long)f;
+ }
+
+ public override float DecodeNormValue(long norm)
+ {
+ return norm;
+ }
+
+ public override float LengthNorm(FieldInvertState state)
+ {
+ return state.Length;
+ }
+
+ public override float Coord(int overlap, int maxOverlap)
+ {
+ return 0;
+ }
+
+ public override float QueryNorm(float sumOfSquaredWeights)
+ {
+ return 0;
+ }
+
+ public override float Tf(float freq)
+ {
+ return 0;
+ }
+
+ public override float Idf(long docFreq, long numDocs)
+ {
+ return 0;
+ }
+
+ public override float SloppyFreq(int distance)
+ {
+ return 0;
+ }
+
+ public override float ScorePayload(int doc, int start, int end, BytesRef payload)
+ {
+ return 0;
+ }
+ }
+
+ // LUCENE-1260
+ [Test]
+ public virtual void TestCustomEncoder()
+ {
+ Directory dir = NewDirectory();
+ MockAnalyzer analyzer = new MockAnalyzer(Random());
+
+ IndexWriterConfig config = NewIndexWriterConfig(TEST_VERSION_CURRENT, analyzer);
+ config.SetSimilarity(new CustomNormEncodingSimilarity(this));
+ RandomIndexWriter writer = new RandomIndexWriter(Random(), dir, config);
+ Document doc = new Document();
+ Field foo = NewTextField("foo", "", Field.Store.NO);
+ Field bar = NewTextField("bar", "", Field.Store.NO);
+ doc.Add(foo);
+ doc.Add(bar);
+
+ for (int i = 0; i < 100; i++)
+ {
+ bar.SetStringValue("singleton");
+ writer.AddDocument(doc);
+ }
+
+ IndexReader reader = writer.Reader;
+ writer.Dispose();
+
+ NumericDocValues fooNorms = MultiDocValues.GetNormValues(reader, "foo");
+ for (int i = 0; i < reader.MaxDoc; i++)
+ {
+ Assert.AreEqual(0, fooNorms.Get(i));
+ }
+
+ NumericDocValues barNorms = MultiDocValues.GetNormValues(reader, "bar");
+ for (int i = 0; i < reader.MaxDoc; i++)
+ {
+ Assert.AreEqual(1, barNorms.Get(i));
+ }
+
+ reader.Dispose();
+ dir.Dispose();
+ }
+
+ [Test]
+ public virtual void TestMaxByteNorms()
+ {
+ Directory dir = NewFSDirectory(CreateTempDir("TestNorms.testMaxByteNorms"));
+ BuildIndex(dir);
+ AtomicReader open = SlowCompositeReaderWrapper.Wrap(DirectoryReader.Open(dir));
+ NumericDocValues normValues = open.GetNormValues(ByteTestField);
+ Assert.IsNotNull(normValues);
+ for (int i = 0; i < open.MaxDoc; i++)
+ {
+ Document document = open.Document(i);
+ int expected = Convert.ToInt32(document.Get(ByteTestField));
+ Assert.AreEqual(expected, normValues.Get(i) & 0xff);
+ }
+ open.Dispose();
+ dir.Dispose();
+ }
+
+ // TODO: create a testNormsNotPresent ourselves by adding/deleting/merging docs
+
+ public virtual void BuildIndex(Directory dir)
+ {
+ Random random = Random();
+ MockAnalyzer analyzer = new MockAnalyzer(Random());
+ analyzer.MaxTokenLength = TestUtil.NextInt(Random(), 1, IndexWriter.MAX_TERM_LENGTH);
+ IndexWriterConfig config = NewIndexWriterConfig(TEST_VERSION_CURRENT, analyzer);
+ Similarity provider = new MySimProvider(this);
+ config.SetSimilarity(provider);
+ RandomIndexWriter writer = new RandomIndexWriter(random, dir, config);
+ LineFileDocs docs = new LineFileDocs(random, DefaultCodecSupportsDocValues());
+ int num = AtLeast(100);
+ for (int i = 0; i < num; i++)
+ {
+ Document doc = docs.NextDoc();
+ int boost = Random().Next(255);
+ Field f = new TextField(ByteTestField, "" + boost, Field.Store.YES);
+ f.Boost = boost;
+ doc.Add(f);
+ writer.AddDocument(doc);
+ doc.RemoveField(ByteTestField);
+ if (Rarely())
+ {
+ writer.Commit();
+ }
+ }
+ writer.Commit();
+ writer.Dispose();
+ docs.Dispose();
+ }
+
+ public class MySimProvider : PerFieldSimilarityWrapper
+ {
+ private readonly TestNorms OuterInstance;
+
+ public MySimProvider(TestNorms outerInstance)
+ {
+ this.OuterInstance = outerInstance;
+ }
+
+ internal Similarity @delegate = new DefaultSimilarity();
+
+ public override float QueryNorm(float sumOfSquaredWeights)
+ {
+ return @delegate.QueryNorm(sumOfSquaredWeights);
+ }
+
+ public override Similarity Get(string field)
+ {
+ if (OuterInstance.ByteTestField.Equals(field))
+ {
+ return new ByteEncodingBoostSimilarity();
+ }
+ else
+ {
+ return @delegate;
+ }
+ }
+
+ public override float Coord(int overlap, int maxOverlap)
+ {
+ return @delegate.Coord(overlap, maxOverlap);
+ }
+ }
+
+ public class ByteEncodingBoostSimilarity : Similarity
+ {
+ public override long ComputeNorm(FieldInvertState state)
+ {
+ int boost = (int)state.Boost;
+ return (sbyte)boost;
+ }
+
+ public override SimWeight ComputeWeight(float queryBoost, CollectionStatistics collectionStats, params TermStatistics[] termStats)
+ {
+ throw new System.NotSupportedException();
+ }
+
+ public override SimScorer GetSimScorer(SimWeight weight, AtomicReaderContext context)
+ {
+ throw new System.NotSupportedException();
+ }
+ }
+ }
+}
\ No newline at end of file