cvsimport
[beagle.git] / beagled / Lucene.Net / Search / FieldCacheImpl.cs
blob5465160420e4bad03f0c414da19128d0d7d0b808
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.
17 using System;
18 using IndexReader = Lucene.Net.Index.IndexReader;
19 using Term = Lucene.Net.Index.Term;
20 using TermDocs = Lucene.Net.Index.TermDocs;
21 using TermEnum = Lucene.Net.Index.TermEnum;
22 using StringIndex = Lucene.Net.Search.StringIndex;
24 namespace Lucene.Net.Search
27 /// <summary> Expert: The default cache implementation, storing all values in memory.
28 /// A WeakHashMap is used for storage.
29 ///
30 /// <p>Created: May 19, 2004 4:40:36 PM
31 ///
32 /// </summary>
33 /// <author> Tim Jones (Nacimiento Software)
34 /// </author>
35 /// <since> lucene 1.4
36 /// </since>
37 /// <version> $Id: FieldCacheImpl.cs,v 1.3 2006/10/02 17:09:02 joeshaw Exp $
38 /// </version>
39 class FieldCacheImpl : FieldCache
41 public class AnonymousClassIntParser : IntParser
43 public virtual int ParseInt(System.String value_Renamed)
45 return System.Int32.Parse(value_Renamed);
48 public class AnonymousClassFloatParser : FloatParser
50 public virtual float ParseFloat(System.String value_Renamed)
52 return System.Single.Parse(value_Renamed);
56 /// <summary>Expert: Every key in the internal cache is of this type. </summary>
57 internal class Entry
59 internal System.String field; // which Field
60 internal int type; // which SortField type
61 internal System.Object custom; // which custom comparator
63 /// <summary>Creates one of these objects. </summary>
64 internal Entry(System.String field, int type)
66 this.field = String.Intern(field);
67 this.type = type;
68 this.custom = null;
71 /// <summary>Creates one of these objects for a custom comparator. </summary>
72 internal Entry(System.String field, System.Object custom)
74 this.field = String.Intern(field);
75 this.type = SortField.CUSTOM;
76 this.custom = custom;
79 /// <summary>Two of these are equal iff they reference the same field and type. </summary>
80 public override bool Equals(System.Object o)
82 if (o is Entry)
84 Entry other = (Entry) o;
85 if (other.field == field && other.type == type)
87 if (other.custom == null)
89 if (custom == null)
90 return true;
92 else if (other.custom.Equals(custom))
94 return true;
98 return false;
101 /// <summary>Composes a hashcode based on the field and type. </summary>
102 public override int GetHashCode()
104 return field.GetHashCode() ^ type ^ (custom == null?0:custom.GetHashCode());
108 private static readonly IntParser INT_PARSER;
110 private static readonly FloatParser FLOAT_PARSER;
112 /// <summary>The internal cache. Maps Entry to array of interpreted term values. *</summary>
113 internal System.Collections.IDictionary cache = new System.Collections.Hashtable();
115 /// <summary>See if an object is in the cache. </summary>
116 internal virtual System.Object Lookup(IndexReader reader, System.String field, int type)
118 Entry entry = new Entry(field, type);
119 lock (this)
121 System.Collections.Hashtable readerCache = (System.Collections.Hashtable) cache[reader];
122 if (readerCache == null)
123 return null;
124 return readerCache[entry];
128 /// <summary>See if a custom object is in the cache. </summary>
129 internal virtual System.Object Lookup(IndexReader reader, System.String field, System.Object comparer)
131 Entry entry = new Entry(field, comparer);
132 lock (this)
134 System.Collections.Hashtable readerCache = (System.Collections.Hashtable) cache[reader];
135 if (readerCache == null)
136 return null;
137 return readerCache[entry];
141 /// <summary>Put an object into the cache. </summary>
142 internal virtual System.Object Store(IndexReader reader, System.String field, int type, System.Object value_Renamed)
144 Entry entry = new Entry(field, type);
145 lock (this)
147 System.Collections.Hashtable readerCache = (System.Collections.Hashtable) cache[reader];
148 if (readerCache == null)
150 readerCache = new System.Collections.Hashtable();
151 cache[reader] = readerCache;
153 System.Object tempObject;
154 tempObject = readerCache[entry];
155 readerCache[entry] = value_Renamed;
156 return tempObject;
160 /// <summary>Put a custom object into the cache. </summary>
161 internal virtual System.Object Store(IndexReader reader, System.String field, System.Object comparer, System.Object value_Renamed)
163 Entry entry = new Entry(field, comparer);
164 lock (this)
166 System.Collections.Hashtable readerCache = (System.Collections.Hashtable) cache[reader];
167 if (readerCache == null)
169 readerCache = new System.Collections.Hashtable();
170 cache[reader] = readerCache;
172 System.Object tempObject;
173 tempObject = readerCache[entry];
174 readerCache[entry] = value_Renamed;
175 return tempObject;
179 // inherit javadocs
180 public virtual int[] GetInts(IndexReader reader, System.String field)
182 return GetInts(reader, field, INT_PARSER);
185 // inherit javadocs
186 public virtual int[] GetInts(IndexReader reader, System.String field, IntParser parser)
188 field = String.Intern(field);
189 System.Object ret = Lookup(reader, field, parser);
190 if (ret == null)
192 int[] retArray = new int[reader.MaxDoc()];
193 if (retArray.Length > 0)
195 TermDocs termDocs = reader.TermDocs();
196 TermEnum termEnum = reader.Terms(new Term(field, ""));
199 if (termEnum.Term() == null)
201 throw new System.SystemException("no terms in field " + field);
205 Term term = termEnum.Term();
206 if (term.Field() != field)
207 break;
208 int termval = parser.ParseInt(term.Text());
209 termDocs.Seek(termEnum);
210 while (termDocs.Next())
212 retArray[termDocs.Doc()] = termval;
215 while (termEnum.Next());
217 finally
219 termDocs.Close();
220 termEnum.Close();
223 Store(reader, field, parser, retArray);
224 return retArray;
226 return (int[]) ret;
229 // inherit javadocs
230 public virtual float[] GetFloats(IndexReader reader, System.String field)
232 return GetFloats(reader, field, FLOAT_PARSER);
235 // inherit javadocs
236 public virtual float[] GetFloats(IndexReader reader, System.String field, FloatParser parser)
238 field = String.Intern(field);
239 System.Object ret = Lookup(reader, field, parser);
240 if (ret == null)
242 float[] retArray = new float[reader.MaxDoc()];
243 if (retArray.Length > 0)
245 TermDocs termDocs = reader.TermDocs();
246 TermEnum termEnum = reader.Terms(new Term(field, ""));
249 if (termEnum.Term() == null)
251 throw new System.SystemException("no terms in field " + field);
255 Term term = termEnum.Term();
256 if (term.Field() != field)
257 break;
258 float termval;
261 termval = SupportClass.Single.Parse(term.Text());
263 catch (Exception e)
265 termval = 0;
267 termDocs.Seek(termEnum);
268 while (termDocs.Next())
270 retArray[termDocs.Doc()] = termval;
273 while (termEnum.Next());
275 finally
277 termDocs.Close();
278 termEnum.Close();
281 Store(reader, field, parser, retArray);
282 return retArray;
284 return (float[]) ret;
287 // inherit javadocs
288 public virtual System.String[] GetStrings(IndexReader reader, System.String field)
290 field = String.Intern(field);
291 System.Object ret = Lookup(reader, field, SortField.STRING);
292 if (ret == null)
294 System.String[] retArray = new System.String[reader.MaxDoc()];
295 if (retArray.Length > 0)
297 TermDocs termDocs = reader.TermDocs();
298 TermEnum termEnum = reader.Terms(new Term(field, ""));
301 if (termEnum.Term() == null)
303 throw new System.SystemException("no terms in field " + field);
307 Term term = termEnum.Term();
308 if (term.Field() != field)
309 break;
310 System.String termval = term.Text();
311 termDocs.Seek(termEnum);
312 while (termDocs.Next())
314 retArray[termDocs.Doc()] = termval;
317 while (termEnum.Next());
319 finally
321 termDocs.Close();
322 termEnum.Close();
325 Store(reader, field, SortField.STRING, retArray);
326 return retArray;
328 return (System.String[]) ret;
331 // inherit javadocs
332 public virtual StringIndex GetStringIndex(IndexReader reader, System.String field)
334 field = String.Intern(field);
335 System.Object ret = Lookup(reader, field, Lucene.Net.Search.FieldCache_Fields.STRING_INDEX);
336 if (ret == null)
338 int[] retArray = new int[reader.MaxDoc()];
339 System.String[] mterms = new System.String[reader.MaxDoc() + 1];
340 if (retArray.Length > 0)
342 TermDocs termDocs = reader.TermDocs();
343 TermEnum termEnum = reader.Terms(new Term(field, ""));
344 int t = 0; // current term number
346 // an entry for documents that have no terms in this field
347 // should a document with no terms be at top or bottom?
348 // this puts them at the top - if it is changed, FieldDocSortedHitQueue
349 // needs to change as well.
350 mterms[t++] = null;
354 if (termEnum.Term() == null)
356 throw new System.SystemException("no terms in field " + field);
360 Term term = termEnum.Term();
361 if (term.Field() != field)
362 break;
364 // store term text
365 // we expect that there is at most one term per document
366 if (t >= mterms.Length)
367 throw new System.SystemException("there are more terms than " + "documents in field \"" + field + "\", but it's impossible to sort on " + "tokenized fields");
368 mterms[t] = term.Text();
370 termDocs.Seek(termEnum);
371 while (termDocs.Next())
373 retArray[termDocs.Doc()] = t;
376 t++;
378 while (termEnum.Next());
380 finally
382 termDocs.Close();
383 termEnum.Close();
386 if (t == 0)
388 // if there are no terms, make the term array
389 // have a single null entry
390 mterms = new System.String[1];
392 else if (t < mterms.Length)
394 // if there are less terms than documents,
395 // trim off the dead array space
396 System.String[] terms = new System.String[t];
397 Array.Copy(mterms, 0, terms, 0, t);
398 mterms = terms;
401 StringIndex value_Renamed = new StringIndex(retArray, mterms);
402 Store(reader, field, Lucene.Net.Search.FieldCache_Fields.STRING_INDEX, value_Renamed);
403 return value_Renamed;
405 return (StringIndex) ret;
408 /// <summary>The pattern used to detect integer values in a field </summary>
409 /// <summary>removed for java 1.3 compatibility
410 /// protected static final Pattern pIntegers = Pattern.compile ("[0-9\\-]+");
411 ///
412 /// </summary>
414 /// <summary>The pattern used to detect float values in a field </summary>
415 /// <summary> removed for java 1.3 compatibility
416 /// protected static final Object pFloats = Pattern.compile ("[0-9+\\-\\.eEfFdD]+");
417 /// </summary>
419 // inherit javadocs
420 public virtual System.Object GetAuto(IndexReader reader, System.String field)
422 field = String.Intern(field);
423 System.Object ret = Lookup(reader, field, SortField.AUTO);
424 if (ret == null)
426 TermEnum enumerator = reader.Terms(new Term(field, ""));
429 Term term = enumerator.Term();
430 if (term == null)
432 throw new System.SystemException("no terms in field " + field + " - cannot determine sort type");
434 if (term.Field() == field)
436 System.String termtext = term.Text().Trim();
439 * Java 1.4 level code:
441 if (pIntegers.matcher(termtext).matches())
442 return IntegerSortedHitQueue.comparator (reader, enumerator, field);
444 else if (pFloats.matcher(termtext).matches())
445 return FloatSortedHitQueue.comparator (reader, enumerator, field);
448 // Java 1.3 level code:
451 System.Int32.Parse(termtext);
452 ret = GetInts(reader, field);
454 catch (System.FormatException nfe1)
458 System.Single.Parse(termtext);
459 ret = GetFloats(reader, field);
461 catch (System.FormatException nfe2)
463 ret = GetStringIndex(reader, field);
466 if (ret != null)
468 Store(reader, field, SortField.AUTO, ret);
471 else
473 throw new System.SystemException("field \"" + field + "\" does not appear to be indexed");
476 finally
478 enumerator.Close();
481 return ret;
484 // inherit javadocs
485 public virtual System.IComparable[] GetCustom(IndexReader reader, System.String field, SortComparator comparator)
487 field = String.Intern(field);
488 System.Object ret = Lookup(reader, field, comparator);
489 if (ret == null)
491 System.IComparable[] retArray = new System.IComparable[reader.MaxDoc()];
492 if (retArray.Length > 0)
494 TermDocs termDocs = reader.TermDocs();
495 TermEnum termEnum = reader.Terms(new Term(field, ""));
498 if (termEnum.Term() == null)
500 throw new System.SystemException("no terms in field " + field);
504 Term term = termEnum.Term();
505 if (term.Field() != field)
506 break;
507 System.IComparable termval = comparator.GetComparable(term.Text());
508 termDocs.Seek(termEnum);
509 while (termDocs.Next())
511 retArray[termDocs.Doc()] = termval;
514 while (termEnum.Next());
516 finally
518 termDocs.Close();
519 termEnum.Close();
522 Store(reader, field, comparator, retArray);
523 return retArray;
525 return (System.IComparable[]) ret;
527 static FieldCacheImpl()
529 INT_PARSER = new AnonymousClassIntParser();
530 FLOAT_PARSER = new AnonymousClassFloatParser();