KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > lucene > search > FieldCacheImpl


1 package org.apache.lucene.search;
2
3 /**
4  * Copyright 2004 The Apache Software Foundation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import org.apache.lucene.index.IndexReader;
20 import org.apache.lucene.index.Term;
21 import org.apache.lucene.index.TermDocs;
22 import org.apache.lucene.index.TermEnum;
23 import org.apache.lucene.search.FieldCache.StringIndex; // required by GCJ
24

25 import java.io.IOException JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.WeakHashMap JavaDoc;
28 import java.util.HashMap JavaDoc;
29
30 /**
31  * Expert: The default cache implementation, storing all values in memory.
32  * A WeakHashMap is used for storage.
33  *
34  * <p>Created: May 19, 2004 4:40:36 PM
35  *
36  * @author Tim Jones (Nacimiento Software)
37  * @since lucene 1.4
38  * @version $Id: FieldCacheImpl.java 377502 2006-02-13 21:46:13Z yonik $
39  */

40 class FieldCacheImpl
41 implements FieldCache {
42
43   /** Expert: Every key in the internal cache is of this type. */
44   static class Entry {
45     final String JavaDoc field; // which Field
46
final int type; // which SortField type
47
final Object JavaDoc custom; // which custom comparator
48

49     /** Creates one of these objects. */
50     Entry (String JavaDoc field, int type) {
51       this.field = field.intern();
52       this.type = type;
53       this.custom = null;
54     }
55
56     /** Creates one of these objects for a custom comparator. */
57     Entry (String JavaDoc field, Object JavaDoc custom) {
58       this.field = field.intern();
59       this.type = SortField.CUSTOM;
60       this.custom = custom;
61     }
62
63     /** Two of these are equal iff they reference the same field and type. */
64     public boolean equals (Object JavaDoc o) {
65       if (o instanceof Entry) {
66         Entry other = (Entry) o;
67         if (other.field == field && other.type == type) {
68           if (other.custom == null) {
69             if (custom == null) return true;
70           } else if (other.custom.equals (custom)) {
71             return true;
72           }
73         }
74       }
75       return false;
76     }
77
78     /** Composes a hashcode based on the field and type. */
79     public int hashCode() {
80       return field.hashCode() ^ type ^ (custom==null ? 0 : custom.hashCode());
81     }
82   }
83
84   private static final IntParser INT_PARSER = new IntParser() {
85       public int parseInt(String JavaDoc value) {
86         return Integer.parseInt(value);
87       }
88     };
89
90   private static final FloatParser FLOAT_PARSER = new FloatParser() {
91       public float parseFloat(String JavaDoc value) {
92         return Float.parseFloat(value);
93       }
94     };
95
96   /** The internal cache. Maps Entry to array of interpreted term values. **/
97   final Map JavaDoc cache = new WeakHashMap JavaDoc();
98
99   /** See if an object is in the cache. */
100   Object JavaDoc lookup (IndexReader reader, String JavaDoc field, int type) {
101     Entry entry = new Entry (field, type);
102     synchronized (this) {
103       HashMap JavaDoc readerCache = (HashMap JavaDoc)cache.get(reader);
104       if (readerCache == null) return null;
105       return readerCache.get (entry);
106     }
107   }
108
109   /** See if a custom object is in the cache. */
110   Object JavaDoc lookup (IndexReader reader, String JavaDoc field, Object JavaDoc comparer) {
111     Entry entry = new Entry (field, comparer);
112     synchronized (this) {
113       HashMap JavaDoc readerCache = (HashMap JavaDoc)cache.get(reader);
114       if (readerCache == null) return null;
115       return readerCache.get (entry);
116     }
117   }
118
119   /** Put an object into the cache. */
120   Object JavaDoc store (IndexReader reader, String JavaDoc field, int type, Object JavaDoc value) {
121     Entry entry = new Entry (field, type);
122     synchronized (this) {
123       HashMap JavaDoc readerCache = (HashMap JavaDoc)cache.get(reader);
124       if (readerCache == null) {
125         readerCache = new HashMap JavaDoc();
126         cache.put(reader,readerCache);
127       }
128       return readerCache.put (entry, value);
129     }
130   }
131
132   /** Put a custom object into the cache. */
133   Object JavaDoc store (IndexReader reader, String JavaDoc field, Object JavaDoc comparer, Object JavaDoc value) {
134     Entry entry = new Entry (field, comparer);
135     synchronized (this) {
136       HashMap JavaDoc readerCache = (HashMap JavaDoc)cache.get(reader);
137       if (readerCache == null) {
138         readerCache = new HashMap JavaDoc();
139         cache.put(reader, readerCache);
140       }
141       return readerCache.put (entry, value);
142     }
143   }
144
145   // inherit javadocs
146
public int[] getInts (IndexReader reader, String JavaDoc field) throws IOException JavaDoc {
147     return getInts(reader, field, INT_PARSER);
148   }
149
150   // inherit javadocs
151
public int[] getInts (IndexReader reader, String JavaDoc field, IntParser parser)
152   throws IOException JavaDoc {
153     field = field.intern();
154     Object JavaDoc ret = lookup (reader, field, parser);
155     if (ret == null) {
156       final int[] retArray = new int[reader.maxDoc()];
157       TermDocs termDocs = reader.termDocs();
158       TermEnum termEnum = reader.terms (new Term (field, ""));
159       try {
160         do {
161           Term term = termEnum.term();
162           if (term==null || term.field() != field) break;
163           int termval = parser.parseInt(term.text());
164           termDocs.seek (termEnum);
165           while (termDocs.next()) {
166             retArray[termDocs.doc()] = termval;
167           }
168         } while (termEnum.next());
169       } finally {
170         termDocs.close();
171         termEnum.close();
172       }
173       store (reader, field, parser, retArray);
174       return retArray;
175     }
176     return (int[]) ret;
177   }
178
179   // inherit javadocs
180
public float[] getFloats (IndexReader reader, String JavaDoc field)
181     throws IOException JavaDoc {
182     return getFloats(reader, field, FLOAT_PARSER);
183   }
184
185   // inherit javadocs
186
public float[] getFloats (IndexReader reader, String JavaDoc field,
187                             FloatParser parser) throws IOException JavaDoc {
188     field = field.intern();
189     Object JavaDoc ret = lookup (reader, field, parser);
190     if (ret == null) {
191       final float[] retArray = new float[reader.maxDoc()];
192       TermDocs termDocs = reader.termDocs();
193       TermEnum termEnum = reader.terms (new Term (field, ""));
194       try {
195         do {
196           Term term = termEnum.term();
197           if (term==null || term.field() != field) break;
198           float termval = parser.parseFloat(term.text());
199           termDocs.seek (termEnum);
200           while (termDocs.next()) {
201             retArray[termDocs.doc()] = termval;
202           }
203         } while (termEnum.next());
204       } finally {
205         termDocs.close();
206         termEnum.close();
207       }
208       store (reader, field, parser, retArray);
209       return retArray;
210     }
211     return (float[]) ret;
212   }
213
214   // inherit javadocs
215
public String JavaDoc[] getStrings (IndexReader reader, String JavaDoc field)
216   throws IOException JavaDoc {
217     field = field.intern();
218     Object JavaDoc ret = lookup (reader, field, SortField.STRING);
219     if (ret == null) {
220       final String JavaDoc[] retArray = new String JavaDoc[reader.maxDoc()];
221       TermDocs termDocs = reader.termDocs();
222       TermEnum termEnum = reader.terms (new Term (field, ""));
223       try {
224         do {
225           Term term = termEnum.term();
226           if (term==null || term.field() != field) break;
227           String JavaDoc termval = term.text();
228           termDocs.seek (termEnum);
229           while (termDocs.next()) {
230             retArray[termDocs.doc()] = termval;
231           }
232         } while (termEnum.next());
233       } finally {
234         termDocs.close();
235         termEnum.close();
236       }
237       store (reader, field, SortField.STRING, retArray);
238       return retArray;
239     }
240     return (String JavaDoc[]) ret;
241   }
242
243   // inherit javadocs
244
public StringIndex getStringIndex (IndexReader reader, String JavaDoc field)
245   throws IOException JavaDoc {
246     field = field.intern();
247     Object JavaDoc ret = lookup (reader, field, STRING_INDEX);
248     if (ret == null) {
249       final int[] retArray = new int[reader.maxDoc()];
250       String JavaDoc[] mterms = new String JavaDoc[reader.maxDoc()+1];
251       TermDocs termDocs = reader.termDocs();
252       TermEnum termEnum = reader.terms (new Term (field, ""));
253       int t = 0; // current term number
254

255       // an entry for documents that have no terms in this field
256
// should a document with no terms be at top or bottom?
257
// this puts them at the top - if it is changed, FieldDocSortedHitQueue
258
// needs to change as well.
259
mterms[t++] = null;
260
261       try {
262         do {
263           Term term = termEnum.term();
264           if (term==null || term.field() != field) break;
265
266           // store term text
267
// we expect that there is at most one term per document
268
if (t >= mterms.length) throw new RuntimeException JavaDoc ("there are more terms than " +
269                   "documents in field \"" + field + "\", but it's impossible to sort on " +
270                   "tokenized fields");
271           mterms[t] = term.text();
272
273           termDocs.seek (termEnum);
274           while (termDocs.next()) {
275             retArray[termDocs.doc()] = t;
276           }
277
278           t++;
279         } while (termEnum.next());
280       } finally {
281         termDocs.close();
282         termEnum.close();
283       }
284
285       if (t == 0) {
286         // if there are no terms, make the term array
287
// have a single null entry
288
mterms = new String JavaDoc[1];
289       } else if (t < mterms.length) {
290         // if there are less terms than documents,
291
// trim off the dead array space
292
String JavaDoc[] terms = new String JavaDoc[t];
293         System.arraycopy (mterms, 0, terms, 0, t);
294         mterms = terms;
295       }
296
297       StringIndex value = new StringIndex (retArray, mterms);
298       store (reader, field, STRING_INDEX, value);
299       return value;
300     }
301     return (StringIndex) ret;
302   }
303
304   /** The pattern used to detect integer values in a field */
305   /** removed for java 1.3 compatibility
306    protected static final Pattern pIntegers = Pattern.compile ("[0-9\\-]+");
307    **/

308
309   /** The pattern used to detect float values in a field */
310   /**
311    * removed for java 1.3 compatibility
312    * protected static final Object pFloats = Pattern.compile ("[0-9+\\-\\.eEfFdD]+");
313    */

314
315   // inherit javadocs
316
public Object JavaDoc getAuto (IndexReader reader, String JavaDoc field)
317   throws IOException JavaDoc {
318     field = field.intern();
319     Object JavaDoc ret = lookup (reader, field, SortField.AUTO);
320     if (ret == null) {
321       TermEnum enumerator = reader.terms (new Term (field, ""));
322       try {
323         Term term = enumerator.term();
324         if (term == null) {
325           throw new RuntimeException JavaDoc ("no terms in field " + field + " - cannot determine sort type");
326         }
327         if (term.field() == field) {
328           String JavaDoc termtext = term.text().trim();
329
330           /**
331            * Java 1.4 level code:
332
333            if (pIntegers.matcher(termtext).matches())
334            return IntegerSortedHitQueue.comparator (reader, enumerator, field);
335
336            else if (pFloats.matcher(termtext).matches())
337            return FloatSortedHitQueue.comparator (reader, enumerator, field);
338            */

339
340           // Java 1.3 level code:
341
try {
342             Integer.parseInt (termtext);
343             ret = getInts (reader, field);
344           } catch (NumberFormatException JavaDoc nfe1) {
345             try {
346               Float.parseFloat (termtext);
347               ret = getFloats (reader, field);
348             } catch (NumberFormatException JavaDoc nfe2) {
349               ret = getStringIndex (reader, field);
350             }
351           }
352           if (ret != null) {
353             store (reader, field, SortField.AUTO, ret);
354           }
355         } else {
356           throw new RuntimeException JavaDoc ("field \"" + field + "\" does not appear to be indexed");
357         }
358       } finally {
359         enumerator.close();
360       }
361
362     }
363     return ret;
364   }
365
366   // inherit javadocs
367
public Comparable JavaDoc[] getCustom (IndexReader reader, String JavaDoc field, SortComparator comparator)
368   throws IOException JavaDoc {
369     field = field.intern();
370     Object JavaDoc ret = lookup (reader, field, comparator);
371     if (ret == null) {
372       final Comparable JavaDoc[] retArray = new Comparable JavaDoc[reader.maxDoc()];
373       TermDocs termDocs = reader.termDocs();
374       TermEnum termEnum = reader.terms (new Term (field, ""));
375       try {
376         do {
377           Term term = termEnum.term();
378           if (term==null || term.field() != field) break;
379           Comparable JavaDoc termval = comparator.getComparable (term.text());
380           termDocs.seek (termEnum);
381           while (termDocs.next()) {
382             retArray[termDocs.doc()] = termval;
383           }
384         } while (termEnum.next());
385       } finally {
386         termDocs.close();
387         termEnum.close();
388       }
389       store (reader, field, comparator, retArray);
390       return retArray;
391     }
392     return (Comparable JavaDoc[]) ret;
393   }
394
395 }
396
397
Popular Tags