Thumbnail file hits. Based on a patch from D Bera
[beagle.git] / beagled / Lucene.Net / Search / FieldCacheImpl.cs
blob9c50cabe0443e011df4936d532455d7561438a21
1 /*
2 * Copyright 2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 using System;
17 using IndexReader = Lucene.Net.Index.IndexReader;
18 using Term = Lucene.Net.Index.Term;
19 using TermDocs = Lucene.Net.Index.TermDocs;
20 using TermEnum = Lucene.Net.Index.TermEnum;
21 namespace Lucene.Net.Search
24 /// <summary> Expert: The default cache implementation, storing all values in memory.
25 /// A WeakHashMap is used for storage.
26 ///
27 /// <p>Created: May 19, 2004 4:40:36 PM
28 ///
29 /// </summary>
30 /// <author> Tim Jones (Nacimiento Software)
31 /// </author>
32 /// <since> lucene 1.4
33 /// </since>
34 /// <version> $Id: FieldCacheImpl.cs,v 1.1 2005/01/17 19:54:30 joeshaw Exp $
35 /// </version>
36 class FieldCacheImpl : FieldCache
39 /// <summary>Expert: Every key in the internal cache is of this type. </summary>
40 internal class Entry
42 internal System.String field; // which Field
43 internal int type; // which SortField type
44 internal System.Object custom; // which custom comparator
46 /// <summary>Creates one of these objects. </summary>
47 internal Entry(System.String field, int type)
49 this.field = String.Intern(field);
50 this.type = type;
51 this.custom = null;
54 /// <summary>Creates one of these objects for a custom comparator. </summary>
55 internal Entry(System.String field, System.Object custom)
57 this.field = String.Intern(field);
58 this.type = SortField.CUSTOM;
59 this.custom = custom;
62 /// <summary>Two of these are equal iff they reference the same field and type. </summary>
63 public override bool Equals(System.Object o)
65 if (o is Entry)
67 Entry other = (Entry) o;
68 if ((System.Object) other.field == (System.Object) field && other.type == type)
70 if (other.custom == null)
72 if (custom == null)
73 return true;
75 else if (other.custom.Equals(custom))
77 return true;
81 return false;
84 /// <summary>Composes a hashcode based on the field and type. </summary>
85 public override int GetHashCode()
87 return field.GetHashCode() ^ type ^ (custom == null ? 0 : custom.GetHashCode());
92 /// <summary>The internal cache. Maps Entry to array of interpreted term values. *</summary>
93 internal System.Collections.IDictionary cache = new System.Collections.Hashtable();
95 /// <summary>See if an object is in the cache. </summary>
96 internal virtual System.Object Lookup(IndexReader reader, System.String field, int type)
98 Entry entry = new Entry(field, type);
99 lock (this)
101 System.Collections.Hashtable readerCache = (System.Collections.Hashtable) cache[reader];
102 if (readerCache == null)
103 return null;
104 return readerCache[entry];
108 /// <summary>See if a custom object is in the cache. </summary>
109 internal virtual System.Object Lookup(IndexReader reader, System.String field, System.Object comparer)
111 Entry entry = new Entry(field, comparer);
112 lock (this)
114 System.Collections.Hashtable readerCache = (System.Collections.Hashtable) cache[reader];
115 if (readerCache == null)
116 return null;
117 return readerCache[entry];
121 /// <summary>Put an object into the cache. </summary>
122 internal virtual System.Object Store(IndexReader reader, System.String field, int type, System.Object value_Renamed)
124 Entry entry = new Entry(field, type);
125 lock (this)
127 System.Collections.Hashtable readerCache = (System.Collections.Hashtable) cache[reader];
128 if (readerCache == null)
130 readerCache = new System.Collections.Hashtable();
131 cache[reader] = readerCache;
133 System.Object tempObject;
134 tempObject = readerCache[entry];
135 readerCache[entry] = value_Renamed;
136 return tempObject;
140 /// <summary>Put a custom object into the cache. </summary>
141 internal virtual System.Object Store(IndexReader reader, System.String field, System.Object comparer, System.Object value_Renamed)
143 Entry entry = new Entry(field, comparer);
144 lock (this)
146 System.Collections.Hashtable readerCache = (System.Collections.Hashtable) cache[reader];
147 if (readerCache == null)
149 readerCache = new System.Collections.Hashtable();
150 cache[reader] = readerCache;
152 System.Object tempObject;
153 tempObject = readerCache[entry];
154 readerCache[entry] = value_Renamed;
155 return tempObject;
159 // inherit javadocs
160 public virtual int[] GetInts(IndexReader reader, System.String field)
162 field = String.Intern(field);
163 System.Object ret = Lookup(reader, field, SortField.INT);
164 if (ret == null)
166 int[] retArray = new int[reader.MaxDoc()];
167 if (retArray.Length > 0)
169 TermDocs termDocs = reader.TermDocs();
170 TermEnum termEnum = reader.Terms(new Term(field, ""));
173 if (termEnum.Term() == null)
175 throw new System.SystemException("no terms in Field " + field);
179 Term term = termEnum.Term();
180 if ((System.Object) term.Field() != (System.Object) field)
181 break;
182 int termval = System.Int32.Parse(term.Text());
183 termDocs.Seek(termEnum);
184 while (termDocs.Next())
186 retArray[termDocs.Doc()] = termval;
189 while (termEnum.Next());
191 finally
193 termDocs.Close();
194 termEnum.Close();
197 Store(reader, field, SortField.INT, retArray);
198 return retArray;
200 return (int[]) ret;
203 // inherit javadocs
204 public virtual float[] GetFloats(IndexReader reader, System.String field)
206 field = String.Intern(field);
207 System.Object ret = Lookup(reader, field, SortField.FLOAT);
208 if (ret == null)
210 float[] retArray = new float[reader.MaxDoc()];
211 if (retArray.Length > 0)
213 TermDocs termDocs = reader.TermDocs();
214 TermEnum termEnum = reader.Terms(new Term(field, ""));
217 if (termEnum.Term() == null)
219 throw new System.SystemException("no terms in Field " + field);
223 Term term = termEnum.Term();
224 if ((System.Object) term.Field() != (System.Object) field)
225 break;
226 float termval;
229 termval = SupportClass.Single.Parse(term.Text());
231 catch (Exception e)
233 termval = 0;
235 termDocs.Seek(termEnum);
236 while (termDocs.Next())
238 retArray[termDocs.Doc()] = termval;
241 while (termEnum.Next());
243 finally
245 termDocs.Close();
246 termEnum.Close();
249 Store(reader, field, SortField.FLOAT, retArray);
250 return retArray;
252 return (float[]) ret;
255 // inherit javadocs
256 public virtual System.String[] GetStrings(IndexReader reader, System.String field)
258 field = String.Intern(field);
259 System.Object ret = Lookup(reader, field, SortField.STRING);
260 if (ret == null)
262 System.String[] retArray = new System.String[reader.MaxDoc()];
263 if (retArray.Length > 0)
265 TermDocs termDocs = reader.TermDocs();
266 TermEnum termEnum = reader.Terms(new Term(field, ""));
269 if (termEnum.Term() == null)
271 throw new System.SystemException("no terms in Field " + field);
275 Term term = termEnum.Term();
276 if ((System.Object) term.Field() != (System.Object) field)
277 break;
278 System.String termval = term.Text();
279 termDocs.Seek(termEnum);
280 while (termDocs.Next())
282 retArray[termDocs.Doc()] = termval;
285 while (termEnum.Next());
287 finally
289 termDocs.Close();
290 termEnum.Close();
293 Store(reader, field, SortField.STRING, retArray);
294 return retArray;
296 return (System.String[]) ret;
299 // inherit javadocs
300 public virtual StringIndex GetStringIndex(IndexReader reader, System.String field)
302 field = String.Intern(field);
303 System.Object ret = Lookup(reader, field, Lucene.Net.Search.FieldCache_Fields.STRING_INDEX);
304 if (ret == null)
306 int[] retArray = new int[reader.MaxDoc()];
307 System.String[] mterms = new System.String[reader.MaxDoc() + 1];
308 if (retArray.Length > 0)
310 TermDocs termDocs = reader.TermDocs();
311 TermEnum termEnum = reader.Terms(new Term(field, ""));
312 int t = 0; // current term number
314 // an entry for documents that have no terms in this Field
315 // should a document with no terms be at top or bottom?
316 // this puts them at the top - if it is changed, FieldDocSortedHitQueue
317 // needs to change as well.
318 mterms[t++] = null;
322 if (termEnum.Term() == null)
324 throw new System.SystemException("no terms in Field " + field);
328 Term term = termEnum.Term();
329 if ((System.Object) term.Field() != (System.Object) field)
330 break;
332 // store term text
333 // we expect that there is at most one term per document
334 if (t >= mterms.Length)
335 throw new System.SystemException("there are more terms than documents in Field \"" + field + "\"");
336 mterms[t] = term.Text();
338 termDocs.Seek(termEnum);
339 while (termDocs.Next())
341 retArray[termDocs.Doc()] = t;
344 t++;
346 while (termEnum.Next());
348 finally
350 termDocs.Close();
351 termEnum.Close();
354 if (t == 0)
356 // if there are no terms, make the term array
357 // have a single null entry
358 mterms = new System.String[1];
360 else if (t < mterms.Length)
362 // if there are less terms than documents,
363 // trim off the dead array space
364 System.String[] terms = new System.String[t];
365 Array.Copy(mterms, 0, terms, 0, t);
366 mterms = terms;
369 StringIndex value_Renamed = new StringIndex(retArray, mterms);
370 Store(reader, field, Lucene.Net.Search.FieldCache_Fields.STRING_INDEX, value_Renamed);
371 return value_Renamed;
373 return (StringIndex) ret;
376 /// <summary>The pattern used to detect integer values in a Field </summary>
377 /// <summary>removed for java 1.3 compatibility
378 /// protected static final Pattern pIntegers = Pattern.compile ("[0-9\\-]+");
379 ///
380 /// </summary>
382 /// <summary>The pattern used to detect float values in a Field </summary>
383 /// <summary> removed for java 1.3 compatibility
384 /// protected static final Object pFloats = Pattern.compile ("[0-9+\\-\\.eEfFdD]+");
385 /// </summary>
387 // inherit javadocs
388 public virtual System.Object GetAuto(IndexReader reader, System.String field)
390 field = String.Intern(field);
391 System.Object ret = Lookup(reader, field, SortField.AUTO);
392 if (ret == null)
394 TermEnum enumerator = reader.Terms(new Term(field, ""));
397 Term term = enumerator.Term();
398 if (term == null)
400 throw new System.SystemException("no terms in Field " + field + " - cannot determine sort type");
402 if ((System.Object) term.Field() == (System.Object) field)
404 System.String termtext = term.Text().Trim();
406 /// <summary> Java 1.4 level code:
407 /// if (pIntegers.matcher(termtext).matches())
408 /// return IntegerSortedHitQueue.comparator (reader, enumerator, Field);
409 /// else if (pFloats.matcher(termtext).matches())
410 /// return FloatSortedHitQueue.comparator (reader, enumerator, Field);
411 /// </summary>
413 // Java 1.3 level code:
416 System.Int32.Parse(termtext);
417 ret = GetInts(reader, field);
419 catch (System.FormatException nfe1)
423 System.Single.Parse(termtext);
424 ret = GetFloats(reader, field);
426 catch (System.FormatException nfe2)
428 ret = GetStringIndex(reader, field);
431 if (ret != null)
433 Store(reader, field, SortField.AUTO, ret);
436 else
438 throw new System.SystemException("Field \"" + field + "\" does not appear to be indexed");
441 finally
443 enumerator.Close();
446 return ret;
449 // inherit javadocs
450 public virtual System.IComparable[] GetCustom(IndexReader reader, System.String field, SortComparator comparator)
452 field = String.Intern(field);
453 System.Object ret = Lookup(reader, field, comparator);
454 if (ret == null)
456 System.IComparable[] retArray = new System.IComparable[reader.MaxDoc()];
457 if (retArray.Length > 0)
459 TermDocs termDocs = reader.TermDocs();
460 TermEnum termEnum = reader.Terms(new Term(field, ""));
463 if (termEnum.Term() == null)
465 throw new System.SystemException("no terms in Field " + field);
469 Term term = termEnum.Term();
470 if ((System.Object) term.Field() != (System.Object) field)
471 break;
472 System.IComparable termval = comparator.GetComparable(term.Text());
473 termDocs.Seek(termEnum);
474 while (termDocs.Next())
476 retArray[termDocs.Doc()] = termval;
479 while (termEnum.Next());
481 finally
483 termDocs.Close();
484 termEnum.Close();
487 Store(reader, field, SortField.CUSTOM, retArray);
488 return retArray;
490 return (System.IComparable[]) ret;