/*
* 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 System.Collections.Generic;
using System.Diagnostics;
using Lucene.Net.Index;
using Lucene.Net.Search;
namespace Lucene.Net.Spatial.Util
{
///
/// Constructs a filter for docs matching any of the terms added to this class.
/// Unlike a RangeFilter this can be used for filtering on multiple terms that are not necessarily in
/// a sequence. An example might be a collection of primary keys from a database query result or perhaps
/// a choice of "category" labels picked by the end user. As a filter, this is much faster than the
/// equivalent query (a BooleanQuery with many "should" TermQueries)
///
public class TermsFilter : Filter
{
private readonly SortedSet terms = new SortedSet();
///
/// Adds a term to the list of acceptable terms
///
///
public void AddTerm(Term term)
{
terms.Add(term);
}
public override DocIdSet GetDocIdSet(IndexReader reader)
{
var result = new FixedBitSet(reader.MaxDoc);
var fields = reader.GetFieldNames(IndexReader.FieldOption.ALL);
if (fields == null || fields.Count == 0)
{
return result;
}
String lastField = null;
TermsEnumCompatibility termsEnum = null;
foreach (Term term in terms)
{
if (!term.Field.Equals(lastField))
{
var termsC = new TermsEnumCompatibility(reader, term.Field);
if (termsC.Term() == null)
{
return result;
}
termsEnum = termsC;
lastField = term.Field;
}
if (terms != null)
{
// TODO this check doesn't make sense, decide which variable its supposed to be for
Debug.Assert(termsEnum != null);
if (termsEnum.SeekCeil(term.Text) == TermsEnumCompatibility.SeekStatus.FOUND)
{
termsEnum.Docs(result);
}
}
}
return result;
}
public override bool Equals(object obj)
{
if (this == obj)
return true;
if ((obj == null) || (obj.GetType() != this.GetType()))
return false;
var test = (TermsFilter)obj;
if (terms == test.terms)
return true;
if (terms == null || terms.Count != test.terms.Count)
return false;
var e1 = terms.GetEnumerator();
var e2 = test.terms.GetEnumerator();
while (e1.MoveNext() && e2.MoveNext())
{
if (!e1.Current.Equals(e2.Current)) return false;
}
return true;
}
public override int GetHashCode()
{
int hash = 9;
foreach (Term term in terms)
{
hash = 31 * hash + term.GetHashCode();
}
return hash;
}
}
}