blob: 005bd0cef569e4845564e97a387627312930d94a [file] [log] [blame]
/*
* 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 System;
using IndexReader = Lucene.Net.Index.IndexReader;
using Term = Lucene.Net.Index.Term;
using StringHelper = Lucene.Net.Util.StringHelper;
namespace Lucene.Net.Search
{
/// <summary> Subclass of FilteredTermEnum for enumerating all terms that match the
/// specified range parameters.
/// <p/>
/// Term enumerations are always ordered by Term.compareTo(). Each term in
/// the enumeration is greater than all that precede it.
/// </summary>
/// <since> 2.9
/// </since>
public class TermRangeTermEnum:FilteredTermEnum
{
private System.Globalization.CompareInfo collator = null;
private bool endEnum = false;
private System.String field;
private System.String upperTermText;
private System.String lowerTermText;
private bool includeLower;
private bool includeUpper;
/// <summary> Enumerates all terms greater/equal than <c>lowerTerm</c>
/// but less/equal than <c>upperTerm</c>.
///
/// If an endpoint is null, 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="reader">
/// </param>
/// <param name="field">An interned field that holds both lower and upper terms.
/// </param>
/// <param name="lowerTermText">The term text at the lower end of the range
/// </param>
/// <param name="upperTermText">The term text at the upper end of the range
/// </param>
/// <param name="includeLower">If true, the <c>lowerTerm</c> is included in the range.
/// </param>
/// <param name="includeUpper">If true, the <c>upperTerm</c> is included in the range.
/// </param>
/// <param name="collator">The collator to use to collate index Terms, to determine their
/// membership in the range bounded by <c>lowerTerm</c> and
/// <c>upperTerm</c>.
///
/// </param>
/// <throws> IOException </throws>
public TermRangeTermEnum(IndexReader reader, System.String field, System.String lowerTermText, System.String upperTermText, bool includeLower, bool includeUpper, System.Globalization.CompareInfo collator)
{
this.collator = collator;
this.upperTermText = upperTermText;
this.lowerTermText = lowerTermText;
this.includeLower = includeLower;
this.includeUpper = includeUpper;
this.field = StringHelper.Intern(field);
// do a little bit of normalization...
// open ended range queries should always be inclusive.
if (this.lowerTermText == null)
{
this.lowerTermText = "";
this.includeLower = true;
}
if (this.upperTermText == null)
{
this.includeUpper = true;
}
System.String startTermText = collator == null?this.lowerTermText:"";
SetEnum(reader.Terms(new Term(this.field, startTermText)));
}
public override float Difference()
{
return 1.0f;
}
public override bool EndEnum()
{
return endEnum;
}
protected internal override bool TermCompare(Term term)
{
if (collator == null)
{
// Use Unicode code point ordering
bool checkLower = !includeLower;
if (term != null && (System.Object) term.Field == (System.Object) field)
{
// interned comparison
if (!checkLower || null == lowerTermText || String.CompareOrdinal(term.Text, lowerTermText) > 0)
{
checkLower = false;
if (upperTermText != null)
{
int compare = String.CompareOrdinal(upperTermText, term.Text);
/*
* if beyond the upper term, or is exclusive and this is equal to
* the upper term, break out
*/
if ((compare < 0) || (!includeUpper && compare == 0))
{
endEnum = true;
return false;
}
}
return true;
}
}
else
{
// break
endEnum = true;
return false;
}
return false;
}
else
{
if (term != null && (System.Object) term.Field == (System.Object) field)
{
// interned comparison
if ((lowerTermText == null || (includeLower?collator.Compare(term.Text.ToString(), lowerTermText.ToString()) >= 0:collator.Compare(term.Text.ToString(), lowerTermText.ToString()) > 0)) && (upperTermText == null || (includeUpper?collator.Compare(term.Text.ToString(), upperTermText.ToString()) <= 0:collator.Compare(term.Text.ToString(), upperTermText.ToString()) < 0)))
{
return true;
}
return false;
}
endEnum = true;
return false;
}
}
}
}