blob: 23d0e417046c2e75c9e20c4808c9558e24a5f271 [file] [log] [blame]
using System.Collections.Generic;
namespace Lucene.Net.Search
{
/*
* 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 BytesRef = Lucene.Net.Util.BytesRef;
using FilteredTermsEnum = Lucene.Net.Index.FilteredTermsEnum;
using TermsEnum = Lucene.Net.Index.TermsEnum;
/// <summary>
/// Subclass of <see cref="FilteredTermsEnum"/> for enumerating all terms that match the
/// specified range parameters.
/// <para>Term enumerations are always ordered by
/// <see cref="FilteredTermsEnum.Comparer"/>. Each term in the enumeration is
/// greater than all that precede it.</para>
/// </summary>
public class TermRangeTermsEnum : FilteredTermsEnum
{
private readonly bool includeLower;
private readonly bool includeUpper;
private readonly BytesRef lowerBytesRef;
private readonly BytesRef upperBytesRef;
private readonly IComparer<BytesRef> termComp;
/// <summary>
/// Enumerates all terms greater/equal than <paramref name="lowerTerm"/>
/// but less/equal than <paramref name="upperTerm"/>.
///
/// If an endpoint is <c>null</c>, it is said to be "open". Either or both
/// endpoints may be open. Open endpoints may not be exclusive
/// (you can't select all but the first or last term without
/// explicitly specifying the term to exclude.)
/// </summary>
/// <param name="tenum">
/// TermsEnum to filter </param>
/// <param name="lowerTerm">
/// The term text at the lower end of the range </param>
/// <param name="upperTerm">
/// The term text at the upper end of the range </param>
/// <param name="includeLower">
/// If true, the <paramref name="lowerTerm"/> is included in the range. </param>
/// <param name="includeUpper">
/// If true, the <paramref name="upperTerm"/> is included in the range. </param>
public TermRangeTermsEnum(TermsEnum tenum, BytesRef lowerTerm, BytesRef upperTerm, bool includeLower, bool includeUpper)
: base(tenum)
{
// do a little bit of normalization...
// open ended range queries should always be inclusive.
if (lowerTerm == null)
{
this.lowerBytesRef = new BytesRef();
this.includeLower = true;
}
else
{
this.lowerBytesRef = lowerTerm;
this.includeLower = includeLower;
}
if (upperTerm == null)
{
this.includeUpper = true;
upperBytesRef = null;
}
else
{
this.includeUpper = includeUpper;
upperBytesRef = upperTerm;
}
SetInitialSeekTerm(lowerBytesRef);
termComp = Comparer;
}
protected override AcceptStatus Accept(BytesRef term)
{
if (!this.includeLower && term.Equals(lowerBytesRef))
{
return AcceptStatus.NO;
}
// Use this field's default sort ordering
if (upperBytesRef != null)
{
int cmp = termComp.Compare(upperBytesRef, term);
/*
* if beyond the upper term, or is exclusive and this is equal to
* the upper term, break out
*/
if ((cmp < 0) || (!includeUpper && cmp == 0))
{
return AcceptStatus.END;
}
}
return AcceptStatus.YES;
}
}
}