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 2016/10/02 10:16:59 UTC
[28/49] lucenenet git commit: Ported Core.TestExternalCodes + fixed
bugs that were preventing it from running.
Ported Core.TestExternalCodes + fixed bugs that were preventing it from running.
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/f4819a3e
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/f4819a3e
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/f4819a3e
Branch: refs/heads/master
Commit: f4819a3e4902fd7c257f70068e511145cbc031e4
Parents: 0e77936
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Sun Sep 11 03:59:31 2016 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Sun Sep 11 04:19:45 2016 +0700
----------------------------------------------------------------------
.../Pulsing/PulsingPostingsReader.cs | 6 +-
src/Lucene.Net.Core/Util/Attribute.cs | 2 +-
src/Lucene.Net.Core/Util/AttributeImpl.cs | 276 +++++++++----------
src/Lucene.Net.Tests/Lucene.Net.Tests.csproj | 1 +
src/Lucene.Net.Tests/core/TestExternalCodecs.cs | 264 +++++++++---------
5 files changed, 273 insertions(+), 276 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f4819a3e/src/Lucene.Net.Codecs/Pulsing/PulsingPostingsReader.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Codecs/Pulsing/PulsingPostingsReader.cs b/src/Lucene.Net.Codecs/Pulsing/PulsingPostingsReader.cs
index 7ab59e9..46e4eb9 100644
--- a/src/Lucene.Net.Codecs/Pulsing/PulsingPostingsReader.cs
+++ b/src/Lucene.Net.Codecs/Pulsing/PulsingPostingsReader.cs
@@ -699,7 +699,7 @@ namespace Lucene.Net.Codecs.Pulsing
///
/// @lucene.internal
/// </summary>
- internal sealed class PulsingEnumAttributeImpl : AttributeImpl, IPulsingEnumAttribute
+ internal sealed class PulsingEnumAttribute : AttributeImpl, IPulsingEnumAttribute
{
// we could store 'other', but what if someone 'chained' multiple postings readers,
// this could cause problems?
@@ -720,13 +720,11 @@ namespace Lucene.Net.Codecs.Pulsing
// and is calling clearAttributes(), so they don't nuke the reuse information!
}
- public override void CopyTo(AttributeImpl target)
+ public override void CopyTo(Util.Attribute target)
{
// this makes no sense for us, because our state is per-docsenum.
// we don't want to copy any stuff over to another docsenum ever!
}
-
}
-
}
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f4819a3e/src/Lucene.Net.Core/Util/Attribute.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Util/Attribute.cs b/src/Lucene.Net.Core/Util/Attribute.cs
index 6d00033..adb4277 100644
--- a/src/Lucene.Net.Core/Util/Attribute.cs
+++ b/src/Lucene.Net.Core/Util/Attribute.cs
@@ -72,7 +72,7 @@ namespace Lucene.Net.Util
}
}
- public string ReflectAsString(bool prependAttClass)
+ public virtual string ReflectAsString(bool prependAttClass)
{
StringBuilder buffer = new StringBuilder();
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f4819a3e/src/Lucene.Net.Core/Util/AttributeImpl.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Util/AttributeImpl.cs b/src/Lucene.Net.Core/Util/AttributeImpl.cs
index f14425b..20fc88a 100644
--- a/src/Lucene.Net.Core/Util/AttributeImpl.cs
+++ b/src/Lucene.Net.Core/Util/AttributeImpl.cs
@@ -5,8 +5,7 @@ using System.Text;
namespace Lucene.Net.Util
{
-
- /*
+ /*
* 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.
@@ -24,150 +23,149 @@ namespace Lucene.Net.Util
*/
- /// <summary>
- /// Base class for Attributes that can be added to a
- /// <seealso cref="Lucene.Net.Util.AttributeSource"/>.
- /// <p>
- /// Attributes are used to add data in a dynamic, yet type-safe way to a source
- /// of usually streamed objects, e. g. a <seealso cref="Lucene.Net.Analysis.TokenStream"/>.
- /// </summary>
- public abstract class AttributeImpl : IAttribute, ICloneable
- {
- /// <summary>
- /// Clears the values in this AttributeImpl and resets it to its
- /// default value. If this implementation implements more than one Attribute interface
- /// it clears all.
- /// </summary>
- public abstract void Clear();
-
- /// <summary>
- /// this method returns the current attribute values as a string in the following format
- /// by calling the <seealso cref="#reflectWith(AttributeReflector)"/> method:
- ///
- /// <ul>
- /// <li><em>iff {@code prependAttClass=true}:</em> {@code "AttributeClass#key=value,AttributeClass#key=value"}
- /// <li><em>iff {@code prependAttClass=false}:</em> {@code "key=value,key=value"}
- /// </ul>
- /// </summary>
- /// <seealso cref= #reflectWith(AttributeReflector) </seealso>
- public string ReflectAsString(bool prependAttClass)
- {
- StringBuilder buffer = new StringBuilder();
- ReflectWith(new AttributeReflectorAnonymousInnerClassHelper(this, prependAttClass, buffer));
- return buffer.ToString();
- }
+ /// <summary>
+ /// Base class for Attributes that can be added to a
+ /// <seealso cref="Lucene.Net.Util.AttributeSource"/>.
+ /// <p>
+ /// Attributes are used to add data in a dynamic, yet type-safe way to a source
+ /// of usually streamed objects, e. g. a <seealso cref="Lucene.Net.Analysis.TokenStream"/>.
+ /// </summary>
+ public abstract class AttributeImpl : Attribute, IAttribute, ICloneable
+ {
+ /// <summary>
+ /// Clears the values in this AttributeImpl and resets it to its
+ /// default value. If this implementation implements more than one Attribute interface
+ /// it clears all.
+ /// </summary>
+ public override abstract void Clear();
- private class AttributeReflectorAnonymousInnerClassHelper : IAttributeReflector
- {
- private readonly AttributeImpl OuterInstance;
+ /// <summary>
+ /// this method returns the current attribute values as a string in the following format
+ /// by calling the <seealso cref="#reflectWith(AttributeReflector)"/> method:
+ ///
+ /// <ul>
+ /// <li><em>iff {@code prependAttClass=true}:</em> {@code "AttributeClass#key=value,AttributeClass#key=value"}
+ /// <li><em>iff {@code prependAttClass=false}:</em> {@code "key=value,key=value"}
+ /// </ul>
+ /// </summary>
+ /// <seealso cref= #reflectWith(AttributeReflector) </seealso>
+ public override string ReflectAsString(bool prependAttClass)
+ {
+ StringBuilder buffer = new StringBuilder();
+ ReflectWith(new AttributeReflectorAnonymousInnerClassHelper(this, prependAttClass, buffer));
+ return buffer.ToString();
+ }
- private bool PrependAttClass;
- private StringBuilder Buffer;
+ private class AttributeReflectorAnonymousInnerClassHelper : IAttributeReflector
+ {
+ private readonly AttributeImpl OuterInstance;
- public AttributeReflectorAnonymousInnerClassHelper(AttributeImpl outerInstance, bool prependAttClass, StringBuilder buffer)
- {
- this.OuterInstance = outerInstance;
- this.PrependAttClass = prependAttClass;
- this.Buffer = buffer;
- }
+ private bool PrependAttClass;
+ private StringBuilder Buffer;
- public void Reflect<T>(string key, object value) where T : IAttribute
- {
- throw new NotImplementedException();
- }
+ public AttributeReflectorAnonymousInnerClassHelper(AttributeImpl outerInstance, bool prependAttClass, StringBuilder buffer)
+ {
+ this.OuterInstance = outerInstance;
+ this.PrependAttClass = prependAttClass;
+ this.Buffer = buffer;
+ }
- public virtual void Reflect(Type attClass, string key, object value)
- {
- if (Buffer.Length > 0)
- {
- Buffer.Append(',');
- }
- if (PrependAttClass)
- {
- Buffer.Append(attClass.Name).Append('#');
- }
- Buffer.Append(key).Append('=').Append((value == null) ? "null" : value);
- }
- }
+ public void Reflect<T>(string key, object value) where T : IAttribute
+ {
+ throw new NotImplementedException();
+ }
- /// <summary>
- /// this method is for introspection of attributes, it should simply
- /// add the key/values this attribute holds to the given <seealso cref="AttributeReflector"/>.
- ///
- /// <p>The default implementation calls <seealso cref="AttributeReflector#reflect"/> for all
- /// non-static fields from the implementing class, using the field name as key
- /// and the field value as value. The Attribute class is also determined by reflection.
- /// Please note that the default implementation can only handle single-Attribute
- /// implementations.
- ///
- /// <p>Custom implementations look like this (e.g. for a combined attribute implementation):
- /// <pre class="prettyprint">
- /// public void reflectWith(AttributeReflector reflector) {
- /// reflector.reflect(CharTermAttribute.class, "term", term());
- /// reflector.reflect(PositionIncrementAttribute.class, "positionIncrement", getPositionIncrement());
- /// }
- /// </pre>
- ///
- /// <p>If you implement this method, make sure that for each invocation, the same set of <seealso cref="Attribute"/>
- /// interfaces and keys are passed to <seealso cref="AttributeReflector#reflect"/> in the same order, but possibly
- /// different values. So don't automatically exclude e.g. {@code null} properties!
- /// </summary>
- /// <seealso cref= #reflectAsString(boolean) </seealso>
- public virtual void ReflectWith(IAttributeReflector reflector)
- {
- Type clazz = this.GetType();
- LinkedList<WeakReference> interfaces = AttributeSource.GetAttributeInterfaces(clazz);
- if (interfaces.Count != 1)
- {
- throw new System.NotSupportedException(clazz.Name + " implements more than one Attribute interface, the default reflectWith() implementation cannot handle this.");
- }
- //LUCENE-TODO unsure about GetType()
- Type interf = (Type)interfaces.First.Value.GetType();
- FieldInfo[] fields = clazz.GetFields(BindingFlags.Instance | BindingFlags.Public);
- try
- {
- for (int i = 0; i < fields.Length; i++)
- {
- FieldInfo f = fields[i];
- if (f.IsStatic)
- {
- continue;
- }
- reflector.Reflect(interf, f.Name, f.GetValue(this));
- }
- }
- catch (Exception)
- {
- // this should never happen, because we're just accessing fields
- // from 'this'
- throw new Exception("Unknown Error");
- }
- }
+ public virtual void Reflect(Type attClass, string key, object value)
+ {
+ if (Buffer.Length > 0)
+ {
+ Buffer.Append(',');
+ }
+ if (PrependAttClass)
+ {
+ Buffer.Append(attClass.Name).Append('#');
+ }
+ Buffer.Append(key).Append('=').Append((value == null) ? "null" : value);
+ }
+ }
- /// <summary>
- /// Copies the values from this Attribute into the passed-in
- /// target attribute. The target implementation must support all the
- /// Attributes this implementation supports.
- /// </summary>
- public abstract void CopyTo(AttributeImpl target);
+ /// <summary>
+ /// this method is for introspection of attributes, it should simply
+ /// add the key/values this attribute holds to the given <seealso cref="AttributeReflector"/>.
+ ///
+ /// <p>The default implementation calls <seealso cref="AttributeReflector#reflect"/> for all
+ /// non-static fields from the implementing class, using the field name as key
+ /// and the field value as value. The Attribute class is also determined by reflection.
+ /// Please note that the default implementation can only handle single-Attribute
+ /// implementations.
+ ///
+ /// <p>Custom implementations look like this (e.g. for a combined attribute implementation):
+ /// <pre class="prettyprint">
+ /// public void reflectWith(AttributeReflector reflector) {
+ /// reflector.reflect(CharTermAttribute.class, "term", term());
+ /// reflector.reflect(PositionIncrementAttribute.class, "positionIncrement", getPositionIncrement());
+ /// }
+ /// </pre>
+ ///
+ /// <p>If you implement this method, make sure that for each invocation, the same set of <seealso cref="Attribute"/>
+ /// interfaces and keys are passed to <seealso cref="AttributeReflector#reflect"/> in the same order, but possibly
+ /// different values. So don't automatically exclude e.g. {@code null} properties!
+ /// </summary>
+ /// <seealso cref= #reflectAsString(boolean) </seealso>
+ public override void ReflectWith(IAttributeReflector reflector)
+ {
+ Type clazz = this.GetType();
+ LinkedList<WeakReference> interfaces = AttributeSource.GetAttributeInterfaces(clazz);
+ if (interfaces.Count != 1)
+ {
+ throw new System.NotSupportedException(clazz.Name + " implements more than one Attribute interface, the default reflectWith() implementation cannot handle this.");
+ }
+ //LUCENE-TODO unsure about GetType()
+ Type interf = (Type)interfaces.First.Value.GetType();
+ FieldInfo[] fields = clazz.GetFields(BindingFlags.Instance | BindingFlags.Public);
+ try
+ {
+ for (int i = 0; i < fields.Length; i++)
+ {
+ FieldInfo f = fields[i];
+ if (f.IsStatic)
+ {
+ continue;
+ }
+ reflector.Reflect(interf, f.Name, f.GetValue(this));
+ }
+ }
+ catch (Exception)
+ {
+ // this should never happen, because we're just accessing fields
+ // from 'this'
+ throw new Exception("Unknown Error");
+ }
+ }
- /// <summary>
- /// Shallow clone. Subclasses must override this if they
- /// need to clone any members deeply,
- /// </summary>
- public object Clone()
- {
- AttributeImpl clone = null;
- try
- {
- clone = (AttributeImpl)base.MemberwiseClone();
- }
- catch (Exception)
- {
- throw new Exception("Clone not supported"); // shouldn't happen
- }
- return clone;
- }
- }
+ /// <summary>
+ /// Copies the values from this Attribute into the passed-in
+ /// target attribute. The target implementation must support all the
+ /// Attributes this implementation supports.
+ /// </summary>
+ public override abstract void CopyTo(Attribute target);
+ /// <summary>
+ /// Shallow clone. Subclasses must override this if they
+ /// need to clone any members deeply,
+ /// </summary>
+ public override object Clone()
+ {
+ AttributeImpl clone = null;
+ try
+ {
+ clone = (AttributeImpl)base.MemberwiseClone();
+ }
+ catch (Exception)
+ {
+ throw new Exception("Clone not supported"); // shouldn't happen
+ }
+ return clone;
+ }
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f4819a3e/src/Lucene.Net.Tests/Lucene.Net.Tests.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Lucene.Net.Tests.csproj b/src/Lucene.Net.Tests/Lucene.Net.Tests.csproj
index a20ba5c..1eab117 100644
--- a/src/Lucene.Net.Tests/Lucene.Net.Tests.csproj
+++ b/src/Lucene.Net.Tests/Lucene.Net.Tests.csproj
@@ -429,6 +429,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="core\TestDemo.cs" />
+ <Compile Include="core\TestExternalCodecs.cs" />
<Compile Include="core\TestMergeSchedulerExternal.cs">
<SubType>Code</SubType>
</Compile>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/f4819a3e/src/Lucene.Net.Tests/core/TestExternalCodecs.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/core/TestExternalCodecs.cs b/src/Lucene.Net.Tests/core/TestExternalCodecs.cs
index 6a6a80a..b8a6683 100644
--- a/src/Lucene.Net.Tests/core/TestExternalCodecs.cs
+++ b/src/Lucene.Net.Tests/core/TestExternalCodecs.cs
@@ -1,9 +1,9 @@
using System;
+using NUnit.Framework;
-namespace org.apache.lucene
+namespace Lucene.Net
{
-
- /*
+ /*
* 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.
@@ -20,135 +20,135 @@ namespace org.apache.lucene
* limitations under the License.
*/
- using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
- using PostingsFormat = Lucene.Net.Codecs.PostingsFormat;
- using Lucene46Codec = Lucene.Net.Codecs.Lucene46.Lucene46Codec;
- using Document = Lucene.Net.Document.Document;
- using Field = Lucene.Net.Document.Field;
- using DirectoryReader = Lucene.Net.Index.DirectoryReader;
- using IndexReader = Lucene.Net.Index.IndexReader;
- using IndexWriter = Lucene.Net.Index.IndexWriter;
- using Term = Lucene.Net.Index.Term;
- using IndexSearcher = Lucene.Net.Search.IndexSearcher;
- using TermQuery = Lucene.Net.Search.TermQuery;
- using BaseDirectoryWrapper = Lucene.Net.Store.BaseDirectoryWrapper;
- using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
- using NUnit.Framework;
-
-
- /* Intentionally outside of oal.index to verify fully
+ using MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
+ using PostingsFormat = Lucene.Net.Codecs.PostingsFormat;
+ using Lucene46Codec = Lucene.Net.Codecs.Lucene46.Lucene46Codec;
+ using Document = Lucene.Net.Documents.Document;
+ using Field = Lucene.Net.Documents.Field;
+ using DirectoryReader = Lucene.Net.Index.DirectoryReader;
+ using IndexReader = Lucene.Net.Index.IndexReader;
+ using IndexWriter = Lucene.Net.Index.IndexWriter;
+ using Term = Lucene.Net.Index.Term;
+ using IndexSearcher = Lucene.Net.Search.IndexSearcher;
+ using TermQuery = Lucene.Net.Search.TermQuery;
+ using BaseDirectoryWrapper = Lucene.Net.Store.BaseDirectoryWrapper;
+ using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
+
+
+ /* Intentionally outside of oal.index to verify fully
external codecs work fine */
- public class TestExternalCodecs : LuceneTestCase
- {
-
- private sealed class CustomPerFieldCodec : Lucene46Codec
- {
-
- internal readonly PostingsFormat RamFormat = PostingsFormat.ForName("RAMOnly");
- internal readonly PostingsFormat DefaultFormat = PostingsFormat.ForName("Lucene41");
- internal readonly PostingsFormat PulsingFormat = PostingsFormat.ForName("Pulsing41");
-
- public override PostingsFormat GetPostingsFormatForField(string field)
- {
- if (field.Equals("field2") || field.Equals("id"))
- {
- return PulsingFormat;
- }
- else if (field.Equals("field1"))
- {
- return DefaultFormat;
- }
- else
- {
- return RamFormat;
- }
- }
- }
-
- // tests storing "id" and "field2" fields as pulsing codec,
- // whose term sort is backwards unicode code point, and
- // storing "field1" as a custom entirely-in-RAM codec
- public virtual void TestPerFieldCodec()
- {
-
- int NUM_DOCS = atLeast(173);
- if (VERBOSE)
- {
- Console.WriteLine("TEST: NUM_DOCS=" + NUM_DOCS);
- }
-
- BaseDirectoryWrapper dir = newDirectory();
- dir.CheckIndexOnClose = false; // we use a custom codec provider
- IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())).setCodec(new CustomPerFieldCodec()).setMergePolicy(newLogMergePolicy(3)));
- Document doc = new Document();
- // uses default codec:
- doc.Add(newTextField("field1", "this field uses the standard codec as the test", Field.Store.NO));
- // uses pulsing codec:
- Field field2 = newTextField("field2", "this field uses the pulsing codec as the test", Field.Store.NO);
- doc.Add(field2);
-
- Field idField = newStringField("id", "", Field.Store.NO);
-
- doc.Add(idField);
- for (int i = 0;i < NUM_DOCS;i++)
- {
- idField.StringValue = "" + i;
- w.addDocument(doc);
- if ((i + 1) % 10 == 0)
- {
- w.commit();
- }
- }
- if (VERBOSE)
- {
- Console.WriteLine("TEST: now delete id=77");
- }
- w.deleteDocuments(new Term("id", "77"));
-
- IndexReader r = DirectoryReader.Open(w, true);
-
- Assert.AreEqual(NUM_DOCS - 1, r.NumDocs());
- IndexSearcher s = newSearcher(r);
- Assert.AreEqual(NUM_DOCS - 1, s.Search(new TermQuery(new Term("field1", "standard")), 1).TotalHits);
- Assert.AreEqual(NUM_DOCS - 1, s.Search(new TermQuery(new Term("field2", "pulsing")), 1).TotalHits);
- r.Close();
-
- if (VERBOSE)
- {
- Console.WriteLine("\nTEST: now delete 2nd doc");
- }
- w.deleteDocuments(new Term("id", "44"));
-
- if (VERBOSE)
- {
- Console.WriteLine("\nTEST: now force merge");
- }
- w.forceMerge(1);
- if (VERBOSE)
- {
- Console.WriteLine("\nTEST: now open reader");
- }
- r = DirectoryReader.Open(w, true);
- Assert.AreEqual(NUM_DOCS - 2, r.MaxDoc());
- Assert.AreEqual(NUM_DOCS - 2, r.NumDocs());
- s = newSearcher(r);
- Assert.AreEqual(NUM_DOCS - 2, s.Search(new TermQuery(new Term("field1", "standard")), 1).TotalHits);
- Assert.AreEqual(NUM_DOCS - 2, s.Search(new TermQuery(new Term("field2", "pulsing")), 1).TotalHits);
- Assert.AreEqual(1, s.Search(new TermQuery(new Term("id", "76")), 1).TotalHits);
- Assert.AreEqual(0, s.Search(new TermQuery(new Term("id", "77")), 1).TotalHits);
- Assert.AreEqual(0, s.Search(new TermQuery(new Term("id", "44")), 1).TotalHits);
-
- if (VERBOSE)
- {
- Console.WriteLine("\nTEST: now close NRT reader");
- }
- r.Close();
-
- w.Dispose();
-
- dir.Dispose();
- }
- }
-
+ public class TestExternalCodecs : LuceneTestCase
+ {
+
+ private sealed class CustomPerFieldCodec : Lucene46Codec
+ {
+
+ internal readonly PostingsFormat RamFormat = Codecs.PostingsFormat.ForName("RAMOnly");
+ internal readonly PostingsFormat DefaultFormat = Codecs.PostingsFormat.ForName("Lucene41");
+ internal readonly PostingsFormat PulsingFormat = Codecs.PostingsFormat.ForName("Pulsing41");
+
+ public override PostingsFormat GetPostingsFormatForField(string field)
+ {
+ if (field.Equals("field2") || field.Equals("id"))
+ {
+ return PulsingFormat;
+ }
+ else if (field.Equals("field1"))
+ {
+ return DefaultFormat;
+ }
+ else
+ {
+ return RamFormat;
+ }
+ }
+ }
+
+ // tests storing "id" and "field2" fields as pulsing codec,
+ // whose term sort is backwards unicode code point, and
+ // storing "field1" as a custom entirely-in-RAM codec
+ [Test]
+ public virtual void TestPerFieldCodec()
+ {
+
+ int NUM_DOCS = AtLeast(173);
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: NUM_DOCS=" + NUM_DOCS);
+ }
+
+ using (BaseDirectoryWrapper dir = NewDirectory())
+ {
+ dir.CheckIndexOnClose = false; // we use a custom codec provider
+ using (IndexWriter w = new IndexWriter(dir, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random())).SetCodec(new CustomPerFieldCodec()).SetMergePolicy(NewLogMergePolicy(3))))
+ {
+ Documents.Document doc = new Documents.Document();
+ // uses default codec:
+ doc.Add(NewTextField("field1", "this field uses the standard codec as the test", Field.Store.NO));
+ // uses pulsing codec:
+ Field field2 = NewTextField("field2", "this field uses the pulsing codec as the test", Field.Store.NO);
+ doc.Add(field2);
+
+ Field idField = NewStringField("id", "", Field.Store.NO);
+
+ doc.Add(idField);
+ for (int i = 0; i < NUM_DOCS; i++)
+ {
+ idField.StringValue = "" + i;
+ w.AddDocument(doc);
+ if ((i + 1) % 10 == 0)
+ {
+ w.Commit();
+ }
+ }
+ if (VERBOSE)
+ {
+ Console.WriteLine("TEST: now delete id=77");
+ }
+ w.DeleteDocuments(new Term("id", "77"));
+
+ using (IndexReader r = DirectoryReader.Open(w, true))
+ {
+ Assert.AreEqual(NUM_DOCS - 1, r.NumDocs);
+ IndexSearcher s = NewSearcher(r);
+ Assert.AreEqual(NUM_DOCS - 1, s.Search(new TermQuery(new Term("field1", "standard")), 1).TotalHits);
+ Assert.AreEqual(NUM_DOCS - 1, s.Search(new TermQuery(new Term("field2", "pulsing")), 1).TotalHits);
+ }
+
+ if (VERBOSE)
+ {
+ Console.WriteLine("\nTEST: now delete 2nd doc");
+ }
+ w.DeleteDocuments(new Term("id", "44"));
+
+ if (VERBOSE)
+ {
+ Console.WriteLine("\nTEST: now force merge");
+ }
+ w.ForceMerge(1);
+ if (VERBOSE)
+ {
+ Console.WriteLine("\nTEST: now open reader");
+ }
+ using (IndexReader r = DirectoryReader.Open(w, true))
+ {
+ Assert.AreEqual(NUM_DOCS - 2, r.MaxDoc);
+ Assert.AreEqual(NUM_DOCS - 2, r.NumDocs);
+ IndexSearcher s = NewSearcher(r);
+ Assert.AreEqual(NUM_DOCS - 2, s.Search(new TermQuery(new Term("field1", "standard")), 1).TotalHits);
+ Assert.AreEqual(NUM_DOCS - 2, s.Search(new TermQuery(new Term("field2", "pulsing")), 1).TotalHits);
+ Assert.AreEqual(1, s.Search(new TermQuery(new Term("id", "76")), 1).TotalHits);
+ Assert.AreEqual(0, s.Search(new TermQuery(new Term("id", "77")), 1).TotalHits);
+ Assert.AreEqual(0, s.Search(new TermQuery(new Term("id", "44")), 1).TotalHits);
+
+ if (VERBOSE)
+ {
+ Console.WriteLine("\nTEST: now close NRT reader");
+ }
+ }
+ }
+ }
+ }
+ }
}
\ No newline at end of file