| using Lucene.Net.Diagnostics; |
| using System; |
| using System.Collections.Generic; |
| using System.Diagnostics; |
| |
| 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 AttributeSource = Lucene.Net.Util.AttributeSource; |
| using IBits = Lucene.Net.Util.IBits; |
| using BytesRef = Lucene.Net.Util.BytesRef; |
| |
| /// <summary> |
| /// Abstract class for enumerating a subset of all terms. |
| /// <para/> |
| /// Term enumerations are always ordered by |
| /// <see cref="Comparer"/>. Each term in the enumeration is |
| /// greater than all that precede it. |
| /// <para/><c>Please note:</c> Consumers of this enumeration cannot |
| /// call <c>Seek()</c>, it is forward only; it throws |
| /// <see cref="NotSupportedException"/> when a seeking method |
| /// is called. |
| /// </summary> |
| public abstract class FilteredTermsEnum : TermsEnum |
| { |
| private BytesRef initialSeekTerm = null; |
| private bool doSeek; |
| private BytesRef actualTerm = null; |
| |
| private readonly TermsEnum tenum; |
| |
| /// <summary> |
| /// Return value, if term should be accepted or the iteration should |
| /// <see cref="END"/>. The <c>*_SEEK</c> values denote, that after handling the current term |
| /// the enum should call <see cref="NextSeekTerm(BytesRef)"/> and step forward. </summary> |
| /// <seealso cref="Accept(BytesRef)"/> |
| protected internal enum AcceptStatus |
| { |
| /// <summary> |
| /// Accept the term and position the enum at the next term. </summary> |
| YES, |
| |
| /// <summary> |
| /// Accept the term and advance (<see cref="FilteredTermsEnum.NextSeekTerm(BytesRef)"/>) |
| /// to the next term. |
| /// </summary> |
| YES_AND_SEEK, |
| |
| /// <summary> |
| /// Reject the term and position the enum at the next term. </summary> |
| NO, |
| |
| /// <summary> |
| /// Reject the term and advance (<see cref="FilteredTermsEnum.NextSeekTerm(BytesRef)"/>) |
| /// to the next term. |
| /// </summary> |
| NO_AND_SEEK, |
| |
| /// <summary> |
| /// Reject the term and stop enumerating. </summary> |
| END |
| } |
| |
| /// <summary> |
| /// Return if term is accepted, not accepted or the iteration should ended |
| /// (and possibly seek). |
| /// </summary> |
| protected abstract AcceptStatus Accept(BytesRef term); |
| |
| /// <summary> |
| /// Creates a filtered <see cref="TermsEnum"/> on a terms enum. </summary> |
| /// <param name="tenum"> the terms enumeration to filter. </param> |
| protected FilteredTermsEnum(TermsEnum tenum) // LUCENENET: CA1012: Abstract types should not have constructors (marked protected) |
| : this(tenum, true) |
| { |
| } |
| |
| /// <summary> |
| /// Creates a filtered <see cref="TermsEnum"/> on a terms enum. </summary> |
| /// <param name="tenum"> the terms enumeration to filter. </param> |
| /// <param name="startWithSeek"> start with seek </param> |
| protected FilteredTermsEnum(TermsEnum tenum, bool startWithSeek) // LUCENENET: CA1012: Abstract types should not have constructors (marked protected) |
| { |
| if (Debugging.AssertsEnabled) Debugging.Assert(tenum != null); |
| this.tenum = tenum; |
| doSeek = startWithSeek; |
| } |
| |
| /// <summary> |
| /// Use this method to set the initial <see cref="BytesRef"/> |
| /// to seek before iterating. This is a convenience method for |
| /// subclasses that do not override <see cref="NextSeekTerm(BytesRef)"/>. |
| /// If the initial seek term is <c>null</c> (default), |
| /// the enum is empty. |
| /// <para/>You can only use this method, if you keep the default |
| /// implementation of <see cref="NextSeekTerm(BytesRef)"/>. |
| /// </summary> |
| protected void SetInitialSeekTerm(BytesRef term) |
| { |
| this.initialSeekTerm = term; |
| } |
| |
| /// <summary> |
| /// On the first call to <see cref="MoveNext()"/> or if <see cref="Accept(BytesRef)"/> returns |
| /// <see cref="AcceptStatus.YES_AND_SEEK"/> or <see cref="AcceptStatus.NO_AND_SEEK"/>, |
| /// this method will be called to eventually seek the underlying <see cref="TermsEnum"/> |
| /// to a new position. |
| /// On the first call, <paramref name="currentTerm"/> will be <c>null</c>, later |
| /// calls will provide the term the underlying enum is positioned at. |
| /// This method returns per default only one time the initial seek term |
| /// and then <c>null</c>, so no repositioning is ever done. |
| /// <para/> |
| /// Override this method, if you want a more sophisticated <see cref="TermsEnum"/>, |
| /// that repositions the iterator during enumeration. |
| /// If this method always returns <c>null</c> the enum is empty. |
| /// <para/><c>Please note:</c> this method should always provide a greater term |
| /// than the last enumerated term, else the behavior of this enum |
| /// violates the contract for <see cref="TermsEnum"/>s. |
| /// </summary> |
| protected virtual BytesRef NextSeekTerm(BytesRef currentTerm) |
| { |
| BytesRef t = initialSeekTerm; |
| initialSeekTerm = null; |
| return t; |
| } |
| |
| /// <summary> |
| /// Returns the related attributes, the returned <see cref="AttributeSource"/> |
| /// is shared with the delegate <see cref="TermsEnum"/>. |
| /// </summary> |
| public override AttributeSource Attributes => tenum.Attributes; |
| |
| public override BytesRef Term => tenum.Term; |
| |
| public override IComparer<BytesRef> Comparer => tenum.Comparer; |
| |
| public override int DocFreq => tenum.DocFreq; |
| |
| public override long TotalTermFreq => tenum.TotalTermFreq; |
| |
| /// <summary> |
| /// this enum does not support seeking! </summary> |
| /// <exception cref="NotSupportedException"> In general, subclasses do not |
| /// support seeking. </exception> |
| public override bool SeekExact(BytesRef term) |
| { |
| throw new NotSupportedException(this.GetType().Name + " does not support seeking"); |
| } |
| |
| /// <summary> |
| /// this enum does not support seeking! </summary> |
| /// <exception cref="NotSupportedException"> In general, subclasses do not |
| /// support seeking. </exception> |
| public override SeekStatus SeekCeil(BytesRef term) |
| { |
| throw new NotSupportedException(this.GetType().Name + " does not support seeking"); |
| } |
| |
| /// <summary> |
| /// this enum does not support seeking! </summary> |
| /// <exception cref="NotSupportedException"> In general, subclasses do not |
| /// support seeking. </exception> |
| public override void SeekExact(long ord) |
| { |
| throw new NotSupportedException(this.GetType().Name + " does not support seeking"); |
| } |
| |
| public override long Ord => tenum.Ord; |
| |
| public override DocsEnum Docs(IBits bits, DocsEnum reuse, DocsFlags flags) |
| { |
| return tenum.Docs(bits, reuse, flags); |
| } |
| |
| public override DocsAndPositionsEnum DocsAndPositions(IBits bits, DocsAndPositionsEnum reuse, DocsAndPositionsFlags flags) |
| { |
| return tenum.DocsAndPositions(bits, reuse, flags); |
| } |
| |
| /// <summary> |
| /// this enum does not support seeking! </summary> |
| /// <exception cref="NotSupportedException"> In general, subclasses do not |
| /// support seeking. </exception> |
| public override void SeekExact(BytesRef term, TermState state) |
| { |
| throw new NotSupportedException(this.GetType().Name + " does not support seeking"); |
| } |
| |
| /// <summary> |
| /// Returns the filtered enums term state |
| /// </summary> |
| public override TermState GetTermState() |
| { |
| if (Debugging.AssertsEnabled) Debugging.Assert(tenum != null); |
| return tenum.GetTermState(); |
| } |
| |
| public override bool MoveNext() |
| { |
| //System.out.println("FTE.next doSeek=" + doSeek); |
| //new Throwable().printStackTrace(System.out); |
| for (; ; ) |
| { |
| // Seek or forward the iterator |
| if (doSeek) |
| { |
| doSeek = false; |
| BytesRef t = NextSeekTerm(actualTerm); |
| //System.out.println(" seek to t=" + (t == null ? "null" : t.utf8ToString()) + " tenum=" + tenum); |
| // Make sure we always seek forward: |
| if (Debugging.AssertsEnabled) Debugging.Assert(actualTerm == null || t == null || Comparer.Compare(t, actualTerm) > 0, "curTerm={0} seekTerm={1}", actualTerm, t); |
| if (t == null || tenum.SeekCeil(t) == SeekStatus.END) |
| { |
| // no more terms to seek to or enum exhausted |
| //System.out.println(" return null"); |
| return false; |
| } |
| actualTerm = tenum.Term; |
| //System.out.println(" got term=" + actualTerm.utf8ToString()); |
| } |
| else |
| { |
| if (tenum.MoveNext()) |
| { |
| actualTerm = tenum.Term; |
| } |
| else |
| { |
| // enum exhausted |
| actualTerm = null; |
| return false; |
| } |
| } |
| |
| // check if term is accepted |
| switch (Accept(actualTerm)) |
| { |
| case FilteredTermsEnum.AcceptStatus.YES_AND_SEEK: |
| doSeek = true; |
| // term accepted, but we need to seek so fall-through |
| goto case FilteredTermsEnum.AcceptStatus.YES; |
| case FilteredTermsEnum.AcceptStatus.YES: |
| // term accepted |
| return true; |
| |
| case FilteredTermsEnum.AcceptStatus.NO_AND_SEEK: |
| // invalid term, seek next time |
| doSeek = true; |
| break; |
| |
| case FilteredTermsEnum.AcceptStatus.END: |
| // we are supposed to end the enum |
| return false; |
| } |
| } |
| } |
| |
| [Obsolete("Use MoveNext() and Term instead. This method will be removed in 4.8.0 release candidate."), System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] |
| public override BytesRef Next() |
| { |
| if (MoveNext()) |
| return actualTerm; |
| return null; |
| } |
| } |
| } |