/* * 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; } } }