This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git

commit 1dc0f320eb4e8e133dddb85fd14cc7f2c2952c51
Author: Shad Storhaug <[email protected]>
AuthorDate: Sat Aug 29 20:38:03 2020 +0700

    Lucene.Net.Util.FilterIterator<T>: Converted to FilterEnumerator<T> using a 
predicate passed into the constructor rather than having to subclass. Swapped 
only usage in FieldFilterAtomicReader with a LINQ query/yield return, since 
performance is better. (see #279)
---
 .../Index/FieldFilterAtomicReader.cs               |  27 +---
 src/Lucene.Net.Tests/Util/TestFilterIterator.cs    | 151 +++++++++++++++------
 src/Lucene.Net/Util/FilterIterator.cs              |  50 +++++++
 3 files changed, 170 insertions(+), 58 deletions(-)

diff --git a/src/Lucene.Net.TestFramework/Index/FieldFilterAtomicReader.cs 
b/src/Lucene.Net.TestFramework/Index/FieldFilterAtomicReader.cs
index f1b2b29..dcdb495 100644
--- a/src/Lucene.Net.TestFramework/Index/FieldFilterAtomicReader.cs
+++ b/src/Lucene.Net.TestFramework/Index/FieldFilterAtomicReader.cs
@@ -1,5 +1,6 @@
 using Lucene.Net.Util;
 using System.Collections.Generic;
+using System.Linq;
 using System.Text;
 
 namespace Lucene.Net.Index
@@ -176,29 +177,15 @@ namespace Lucene.Net.Index
                 this.outerInstance = outerInstance;
             }
 
-            public override int Count =>
-                // this information is not cheap, return -1 like MultiFields 
does:
-                -1;
+            // this information is not cheap, return -1 like MultiFields does:
+            public override int Count => -1;
 
             public override IEnumerator<string> GetEnumerator()
             {
-                return new FilterIteratorAnonymousInnerClassHelper(this, 
base.GetEnumerator());
-            }
-
-            private class FilterIteratorAnonymousInnerClassHelper : 
FilterIterator<string>
-            {
-                private readonly FieldFilterFields outerInstance;
-
-                public 
FilterIteratorAnonymousInnerClassHelper(FieldFilterFields outerInstance, 
IEnumerator<string> iterator)
-                    : base(iterator)
-                {
-                    this.outerInstance = outerInstance;
-                }
-
-                protected override bool PredicateFunction(string field)
-                {
-                    return outerInstance.outerInstance.HasField(field);
-                }
+                // LUCENENET: Performance is better and code simpler with 
simple where clause
+                // and yield return.
+                foreach (var field in m_input.Where((f) => 
outerInstance.HasField(f)))
+                    yield return field;
             }
 
             public override Terms GetTerms(string field)
diff --git a/src/Lucene.Net.Tests/Util/TestFilterIterator.cs 
b/src/Lucene.Net.Tests/Util/TestFilterIterator.cs
index edf8b98..3652c03 100644
--- a/src/Lucene.Net.Tests/Util/TestFilterIterator.cs
+++ b/src/Lucene.Net.Tests/Util/TestFilterIterator.cs
@@ -37,10 +37,105 @@ namespace Lucene.Net.Util
         [Test]
         public virtual void TestEmpty()
         {
+            IEnumerator<string> it = new 
FilterEnumerator<string>(set.GetEnumerator(), (s) => false);
+            AssertNoMore(it);
+        }
+
+        [Test]
+        public virtual void TestA1()
+        {
+            IEnumerator<string> it = new 
FilterEnumerator<string>(set.GetEnumerator(), (s) => "a".Equals(s, 
StringComparison.Ordinal));
+            Assert.IsTrue(it.MoveNext());
+            Assert.AreEqual("a", it.Current);
+            AssertNoMore(it);
+        }
+
+        [Test]
+        public virtual void TestA2()
+        {
+            IEnumerator<string> it = new 
FilterEnumerator<string>(set.GetEnumerator(), (s) => "a".Equals(s, 
StringComparison.Ordinal));
+            // this time without check: Assert.IsTrue(it.hasNext());
+            it.MoveNext();
+            Assert.AreEqual("a", it.Current);
+            AssertNoMore(it);
+        }
+
+        [Test]
+        public virtual void TestB1()
+        {
+            IEnumerator<string> it = new 
FilterEnumerator<string>(set.GetEnumerator(), (s) => "b".Equals(s, 
StringComparison.Ordinal));
+            Assert.IsTrue(it.MoveNext());
+            Assert.AreEqual("b", it.Current);
+            AssertNoMore(it);
+        }
+
+        [Test]
+        public virtual void TestB2()
+        {
+            IEnumerator<string> it = new 
FilterEnumerator<string>(set.GetEnumerator(), (s) => "b".Equals(s, 
StringComparison.Ordinal));
+            // this time without check: Assert.IsTrue(it.hasNext());
+            it.MoveNext();
+            Assert.AreEqual("b", it.Current);
+            AssertNoMore(it);
+        }
+
+        [Test]
+        public virtual void TestAll1()
+        {
+            IEnumerator<string> it = new 
FilterEnumerator<string>(set.GetEnumerator(), (s) => true);
+            Assert.IsTrue(it.MoveNext());
+            Assert.AreEqual("a", it.Current);
+            Assert.IsTrue(it.MoveNext());
+            Assert.AreEqual("b", it.Current);
+            Assert.IsTrue(it.MoveNext());
+            Assert.AreEqual("c", it.Current);
+            AssertNoMore(it);
+        }
+
+        [Test]
+        public virtual void TestAll2()
+        {
+            IEnumerator<string> it = new 
FilterEnumerator<string>(set.GetEnumerator(), (s) => true);
+            it.MoveNext();
+            Assert.AreEqual("a", it.Current);
+            it.MoveNext();
+            Assert.AreEqual("b", it.Current);
+            it.MoveNext();
+            Assert.AreEqual("c", it.Current);
+            AssertNoMore(it);
+        }
+
+        //// LUCENENET specific: .NET doesn't support Remove(), so this test 
doesn't apply
+        //[Test]
+        //public virtual void TestUnmodifiable()
+        //{
+        //    IEnumerator<string> it = new 
FilterEnumerator<string>(Set.GetEnumerator(), (s) => true);
+        //    it.MoveNext();
+        //    Assert.AreEqual("a", it.Current);
+        //    try
+        //    {
+
+        //        it.Remove(); 
+        //        Assert.Fail("Should throw UnsupportedOperationException");
+        //    }
+        //    catch (NotSupportedException)
+        //    {
+        //        // pass
+        //    }
+        //}
+
+
+
+
+        [Test]
+        [Obsolete("This method will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+        public virtual void TestEmptyIterator()
+        {
             IEnumerator<string> it = new 
FilterIteratorAnonymousInnerClassHelper(set.GetEnumerator());
             AssertNoMore(it);
         }
 
+        [Obsolete("This class will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
         private class FilterIteratorAnonymousInnerClassHelper : 
FilterIterator<string>
         {
             public FilterIteratorAnonymousInnerClassHelper(IEnumerator<string> 
iterator)
@@ -55,7 +150,8 @@ namespace Lucene.Net.Util
         }
 
         [Test]
-        public virtual void TestA1()
+        [Obsolete("This method will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+        public virtual void TestA1Iterator()
         {
             IEnumerator<string> it = new 
FilterIteratorAnonymousInnerClassHelper2(set.GetEnumerator());
             Assert.IsTrue(it.MoveNext());
@@ -63,6 +159,7 @@ namespace Lucene.Net.Util
             AssertNoMore(it);
         }
 
+        [Obsolete("This class will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
         private class FilterIteratorAnonymousInnerClassHelper2 : 
FilterIterator<string>
         {
             public 
FilterIteratorAnonymousInnerClassHelper2(IEnumerator<string> iterator)
@@ -77,7 +174,8 @@ namespace Lucene.Net.Util
         }
 
         [Test]
-        public virtual void TestA2()
+        [Obsolete("This method will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+        public virtual void TestA2Iterator()
         {
             IEnumerator<string> it = new 
FilterIteratorAnonymousInnerClassHelper3(set.GetEnumerator());
             // this time without check: Assert.IsTrue(it.hasNext());
@@ -86,6 +184,7 @@ namespace Lucene.Net.Util
             AssertNoMore(it);
         }
 
+        [Obsolete("This class will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
         private class FilterIteratorAnonymousInnerClassHelper3 : 
FilterIterator<string>
         {
             public 
FilterIteratorAnonymousInnerClassHelper3(IEnumerator<string> iterator)
@@ -100,7 +199,8 @@ namespace Lucene.Net.Util
         }
 
         [Test]
-        public virtual void TestB1()
+        [Obsolete("This method will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+        public virtual void TestB1Iterator()
         {
             IEnumerator<string> it = new 
FilterIteratorAnonymousInnerClassHelper4(set.GetEnumerator());
             Assert.IsTrue(it.MoveNext());
@@ -108,6 +208,7 @@ namespace Lucene.Net.Util
             AssertNoMore(it);
         }
 
+        [Obsolete("This class will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
         private class FilterIteratorAnonymousInnerClassHelper4 : 
FilterIterator<string>
         {
             public 
FilterIteratorAnonymousInnerClassHelper4(IEnumerator<string> iterator)
@@ -122,7 +223,8 @@ namespace Lucene.Net.Util
         }
 
         [Test]
-        public virtual void TestB2()
+        [Obsolete("This method will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+        public virtual void TestB2Iterator()
         {
             IEnumerator<string> it = new 
FilterIteratorAnonymousInnerClassHelper5(set.GetEnumerator());
             // this time without check: Assert.IsTrue(it.hasNext());
@@ -131,6 +233,7 @@ namespace Lucene.Net.Util
             AssertNoMore(it);
         }
 
+        [Obsolete("This class will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
         private class FilterIteratorAnonymousInnerClassHelper5 : 
FilterIterator<string>
         {
             public 
FilterIteratorAnonymousInnerClassHelper5(IEnumerator<string> iterator)
@@ -145,7 +248,8 @@ namespace Lucene.Net.Util
         }
 
         [Test]
-        public virtual void TestAll1()
+        [Obsolete("This method will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+        public virtual void TestAll1Iterator()
         {
             IEnumerator<string> it = new 
FilterIteratorAnonymousInnerClassHelper6(set.GetEnumerator());
             Assert.IsTrue(it.MoveNext());
@@ -157,6 +261,7 @@ namespace Lucene.Net.Util
             AssertNoMore(it);
         }
 
+        [Obsolete("This class will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
         private class FilterIteratorAnonymousInnerClassHelper6 : 
FilterIterator<string>
         {
             public 
FilterIteratorAnonymousInnerClassHelper6(IEnumerator<string> iterator)
@@ -171,7 +276,8 @@ namespace Lucene.Net.Util
         }
 
         [Test]
-        public virtual void TestAll2()
+        [Obsolete("This method will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
+        public virtual void TestAll2Iterator()
         {
             IEnumerator<string> it = new 
FilterIteratorAnonymousInnerClassHelper7(set.GetEnumerator());
             it.MoveNext();
@@ -183,6 +289,7 @@ namespace Lucene.Net.Util
             AssertNoMore(it);
         }
 
+        [Obsolete("This class will be removed in 4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
         private class FilterIteratorAnonymousInnerClassHelper7 : 
FilterIterator<string>
         {
             public 
FilterIteratorAnonymousInnerClassHelper7(IEnumerator<string> iterator)
@@ -195,37 +302,5 @@ namespace Lucene.Net.Util
                 return true;
             }
         }
-
-        //// LUCENENET specific: .NET doesn't support Remove(), so this test 
doesn't apply
-        //[Test]
-        //public virtual void TestUnmodifiable()
-        //{
-        //    IEnumerator<string> it = new 
FilterIteratorAnonymousInnerClassHelper8(Set.GetEnumerator());
-        //    it.MoveNext();
-        //    Assert.AreEqual("a", it.Current);
-        //    try
-        //    {
-                
-        //        it.Remove(); 
-        //        Assert.Fail("Should throw UnsupportedOperationException");
-        //    }
-        //    catch (NotSupportedException)
-        //    {
-        //        // pass
-        //    }
-        //}
-
-        //private class FilterIteratorAnonymousInnerClassHelper8 : 
FilterIterator<string>
-        //{
-        //    public 
FilterIteratorAnonymousInnerClassHelper8(IEnumerator<string> iterator)
-        //        : base(iterator)
-        //    {
-        //    }
-
-        //    protected override bool PredicateFunction(string s)
-        //    {
-        //        return true;
-        //    }
-        //}
     }
 }
\ No newline at end of file
diff --git a/src/Lucene.Net/Util/FilterIterator.cs 
b/src/Lucene.Net/Util/FilterIterator.cs
index c8d9578..7742977 100644
--- a/src/Lucene.Net/Util/FilterIterator.cs
+++ b/src/Lucene.Net/Util/FilterIterator.cs
@@ -23,7 +23,57 @@ namespace Lucene.Net.Util
 
     /// <summary>
     /// An <see cref="IEnumerator{T}"/> implementation that filters elements 
with a boolean predicate. </summary>
+    // LUCENENET specific - simplifed the logic, as this is much easier to do 
in .NET
+    public sealed class FilterEnumerator<T> : IEnumerator<T>
+    {
+        private readonly IEnumerator<T> iter;
+        private readonly Predicate<T> predicateFunction;
+        private T current;
+
+        /// <summary>
+        /// Initializes a new instance of <see cref="FilterEnumerator{T}"/> 
with the specified <paramref name="baseEnumerator"/> and <paramref 
name="predicateFunction"/>.
+        /// </summary>
+        /// <param name="baseEnumerator"></param>
+        /// <param name="predicateFunction">Returns <c>true</c>, if this 
element should be set to <see cref="Current"/> by <see 
cref="MoveNext()"/>.</param>
+        public FilterEnumerator(IEnumerator<T> baseEnumerator, Predicate<T> 
predicateFunction)
+        {
+            this.iter = baseEnumerator ?? throw new 
ArgumentNullException(nameof(baseEnumerator));
+            this.predicateFunction = predicateFunction ?? throw new 
ArgumentNullException(nameof(predicateFunction));
+            current = default;
+        }
+
+        public bool MoveNext()
+        {
+            while (iter.MoveNext())
+            {
+                if (predicateFunction(iter.Current))
+                {
+                    current = iter.Current;
+                    return true;
+                }
+            }
+            current = default;
+            return false;
+        }
+
+        // LUCENENET specific - seems logical to call reset on the underlying 
implementation
+        public void Reset()
+        {
+            current = default;
+            iter.Reset();
+        }
+
+        public T Current => current;
+
+        object System.Collections.IEnumerator.Current => current;
+
+        public void Dispose() => iter.Dispose();
+    }
+
+    /// <summary>
+    /// An <see cref="IEnumerator{T}"/> implementation that filters elements 
with a boolean predicate. </summary>
     /// <seealso cref="PredicateFunction(T)"/>
+    [Obsolete("Use FilterEnumerator<T> instead. This class will be removed in 
4.8.0 release candidate."), 
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
     public abstract class FilterIterator<T> : IEnumerator<T>
     {
         private readonly IEnumerator<T> iter;

Reply via email to