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
CompatibilityExtensions.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 #if NET35
20 using Lucene.Net.Support.Compatibility;
21 #else
22 using System.Collections.Concurrent;
23 #endif
24 using System.Diagnostics;
25 using Lucene.Net.Analysis.Tokenattributes;
26 using Lucene.Net.Index;
27 using Lucene.Net.Search;
28 
29 namespace Lucene.Net.Spatial.Util
30 {
31  public static class CompatibilityExtensions
32  {
33  public static void Append(this ITermAttribute termAtt, string str)
34  {
35  termAtt.SetTermBuffer(termAtt.Term + str); // TODO: Not optimal, but works
36  }
37 
38  public static void Append(this ITermAttribute termAtt, char ch)
39  {
40  termAtt.SetTermBuffer(termAtt.Term + new string(new[] { ch })); // TODO: Not optimal, but works
41  }
42 
43  private static readonly ConcurrentDictionary<string, IBits> _docsWithFieldCache = new ConcurrentDictionary<string, IBits>();
44 
45  internal static IBits GetDocsWithField(this FieldCache fc, IndexReader reader, String field)
46  {
47  return _docsWithFieldCache.GetOrAdd(field, f => DocsWithFieldCacheEntry_CreateValue(reader, new Entry(field, null), false));
48  }
49 
50  /// <summary> <p/>
51  /// EXPERT: Instructs the FieldCache to forcibly expunge all entries
52  /// from the underlying caches. This is intended only to be used for
53  /// test methods as a way to ensure a known base state of the Cache
54  /// (with out needing to rely on GC to free WeakReferences).
55  /// It should not be relied on for "Cache maintenance" in general
56  /// application code.
57  /// <p/>
58  /// <p/>
59  /// <b>EXPERIMENTAL API:</b> This API is considered extremely advanced
60  /// and experimental. It may be removed or altered w/o warning in future
61  /// releases
62  /// of Lucene.
63  /// <p/>
64  /// </summary>
65  public static void PurgeSpatialCaches(this FieldCache fc)
66  {
67  _docsWithFieldCache.Clear();
68  }
69 
70  private static IBits DocsWithFieldCacheEntry_CreateValue(IndexReader reader, Entry entryKey, bool setDocsWithField /* ignored */)
71  {
72  var field = entryKey.field;
73  FixedBitSet res = null;
74  var terms = new TermsEnumCompatibility(reader, field);
75  var maxDoc = reader.MaxDoc;
76 
77  var term = terms.Next();
78  if (term != null)
79  {
80  int termsDocCount = terms.GetDocCount();
81  Debug.Assert(termsDocCount <= maxDoc);
82  if (termsDocCount == maxDoc)
83  {
84  // Fast case: all docs have this field:
85  return new MatchAllBits(maxDoc);
86  }
87 
88  while (true)
89  {
90  if (res == null)
91  {
92  // lazy init
93  res = new FixedBitSet(maxDoc);
94  }
95 
96  var termDocs = reader.TermDocs(term);
97  while (termDocs.Next())
98  {
99  res.Set(termDocs.Doc);
100  }
101 
102  term = terms.Next();
103  if (term == null)
104  {
105  break;
106  }
107  }
108  }
109  if (res == null)
110  {
111  return new MatchNoBits(maxDoc);
112  }
113  int numSet = res.Cardinality();
114  if (numSet >= maxDoc)
115  {
116  // The cardinality of the BitSet is maxDoc if all documents have a value.
117  Debug.Assert(numSet == maxDoc);
118  return new MatchAllBits(maxDoc);
119  }
120  return res;
121  }
122 
123  /* table of number of leading zeros in a byte */
124  public static readonly byte[] nlzTable = { 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
125 
126  /// <summary>
127  /// Returns the number of leading zero bits.
128  /// </summary>
129  /// <param name="x"></param>
130  /// <returns></returns>
131  public static int BitUtilNlz(long x)
132  {
133  int n = 0;
134  // do the first step as a long
135  var y = (int)((ulong)x >> 32);
136  if (y == 0) { n += 32; y = (int)(x); }
137  if ((y & 0xFFFF0000) == 0) { n += 16; y <<= 16; }
138  if ((y & 0xFF000000) == 0) { n += 8; y <<= 8; }
139  return n + nlzTable[(uint)y >> 24];
140  /* implementation without table:
141  if ((y & 0xF0000000) == 0) { n+=4; y<<=4; }
142  if ((y & 0xC0000000) == 0) { n+=2; y<<=2; }
143  if ((y & 0x80000000) == 0) { n+=1; y<<=1; }
144  if ((y & 0x80000000) == 0) { n+=1;}
145  return n;
146  */
147  }
148  }
149 
150  public static class Arrays
151  {
152  public static void Fill<T>(T[] array, int fromIndex, int toIndex, T value)
153  {
154  if (array == null)
155  {
156  throw new ArgumentNullException("array");
157  }
158  if (fromIndex < 0 || fromIndex > toIndex)
159  {
160  throw new ArgumentOutOfRangeException("fromIndex");
161  }
162  if (toIndex > array.Length)
163  {
164  throw new ArgumentOutOfRangeException("toIndex");
165  }
166  for (var i = fromIndex; i < toIndex; i++)
167  {
168  array[i] = value;
169  }
170  }
171  }
172 
173  /// <summary>
174  /// Expert: Every composite-key in the internal cache is of this type.
175  /// </summary>
176  internal class Entry
177  {
178  internal readonly String field; // which Fieldable
179  internal readonly Object custom; // which custom comparator or parser
180 
181  /* Creates one of these objects for a custom comparator/parser. */
182  public Entry(String field, Object custom)
183  {
184  this.field = field;
185  this.custom = custom;
186  }
187 
188  /* Two of these are equal iff they reference the same field and type. */
189  public override bool Equals(Object o)
190  {
191  var other = o as Entry;
192  if (other != null)
193  {
194  if (other.field.Equals(field))
195  {
196  if (other.custom == null)
197  {
198  if (custom == null) return true;
199  }
200  else if (other.custom.Equals(custom))
201  {
202  return true;
203  }
204  }
205  }
206  return false;
207  }
208 
209  /* Composes a hashcode based on the field and type. */
210  public override int GetHashCode()
211  {
212  return field.GetHashCode() ^ (custom == null ? 0 : custom.GetHashCode());
213  }
214  }
215 }