Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
MultiTermQueryWrapperFilter.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 
20 using IndexReader = Lucene.Net.Index.IndexReader;
21 using Term = Lucene.Net.Index.Term;
22 using TermDocs = Lucene.Net.Index.TermDocs;
23 using TermEnum = Lucene.Net.Index.TermEnum;
24 using OpenBitSet = Lucene.Net.Util.OpenBitSet;
25 
26 namespace Lucene.Net.Search
27 {
28 
29  /// <summary> A wrapper for <see cref="MultiTermQuery" />, that exposes its
30  /// functionality as a <see cref="Filter" />.
31  /// <p/>
32  /// <c>MultiTermQueryWrapperFilter</c> is not designed to
33  /// be used by itself. Normally you subclass it to provide a Filter
34  /// counterpart for a <see cref="MultiTermQuery" /> subclass.
35  /// <p/>
36  /// For example, <see cref="TermRangeFilter" /> and <see cref="PrefixFilter" /> extend
37  /// <c>MultiTermQueryWrapperFilter</c>.
38  /// This class also provides the functionality behind
39  /// <see cref="MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE" />;
40  /// this is why it is not abstract.
41  /// </summary>
42  [Serializable]
43  public class MultiTermQueryWrapperFilter<T> : Filter
44  where T : MultiTermQuery
45  {
46  protected internal T query;
47 
48  /// <summary> Wrap a <see cref="MultiTermQuery" /> as a Filter.</summary>
49  protected internal MultiTermQueryWrapperFilter(T query)
50  {
51  this.query = query;
52  }
53 
54  //@Override
55  public override System.String ToString()
56  {
57  // query.toString should be ok for the filter, too, if the query boost is 1.0f
58  return query.ToString();
59  }
60 
61  //@Override
62  public override bool Equals(System.Object o)
63  {
64  if (o == this)
65  return true;
66  if (o == null)
67  return false;
68  if (this.GetType().Equals(o.GetType()))
69  {
70  return this.query.Equals(((MultiTermQueryWrapperFilter<T>) o).query);
71  }
72  return false;
73  }
74 
75  //@Override
76  public override int GetHashCode()
77  {
78  return query.GetHashCode();
79  }
80 
81  /// <summary> Expert: Return the number of unique terms visited during execution of the filter.
82  /// If there are many of them, you may consider using another filter type
83  /// or optimize your total term count in index.
84  /// <p/>This method is not thread safe, be sure to only call it when no filter is running!
85  /// If you re-use the same filter instance for another
86  /// search, be sure to first reset the term counter
87  /// with <see cref="ClearTotalNumberOfTerms" />.
88  /// </summary>
89  /// <seealso cref="ClearTotalNumberOfTerms">
90  /// </seealso>
91  public virtual int TotalNumberOfTerms
92  {
93  get { return query.TotalNumberOfTerms; }
94  }
95 
96  /// <summary> Expert: Resets the counting of unique terms.
97  /// Do this before executing the filter.
98  /// </summary>
99  /// <seealso cref="TotalNumberOfTerms">
100  /// </seealso>
101  public virtual void ClearTotalNumberOfTerms()
102  {
103  query.ClearTotalNumberOfTerms();
104  }
105 
106  public override DocIdSet GetDocIdSet(IndexReader reader)
107  {
108  TermEnum enumerator = query.GetEnum(reader);
109  try
110  {
111  // if current term in enum is null, the enum is empty -> shortcut
112  if (enumerator.Term == null)
113  return DocIdSet.EMPTY_DOCIDSET;
114  // else fill into an OpenBitSet
115  OpenBitSet bitSet = new OpenBitSet(reader.MaxDoc);
116  int[] docs = new int[32];
117  int[] freqs = new int[32];
118  TermDocs termDocs = reader.TermDocs();
119  try
120  {
121  int termCount = 0;
122  do
123  {
124  Term term = enumerator.Term;
125  if (term == null)
126  break;
127  termCount++;
128  termDocs.Seek(term);
129  while (true)
130  {
131  int count = termDocs.Read(docs, freqs);
132  if (count != 0)
133  {
134  for (int i = 0; i < count; i++)
135  {
136  bitSet.Set(docs[i]);
137  }
138  }
139  else
140  {
141  break;
142  }
143  }
144  } while (enumerator.Next());
145 
146  query.IncTotalNumberOfTerms(termCount); // {{Aroush-2.9}} is the use of 'temp' as is right?
147  }
148  finally
149  {
150  termDocs.Close();
151  }
152 
153  return bitSet;
154  }
155  finally
156  {
157  enumerator.Close();
158  }
159  }
160  }
161 }