1 package org.apache.lucene.search; 2 3 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; 25 import java.io.IOException ; 26 import java.util.Map ; 27 import java.util.WeakHashMap ; 28 import java.util.HashMap ; 29 30 40 class FieldCacheImpl 41 implements FieldCache { 42 43 44 static class Entry { 45 final String field; final int type; final Object custom; 49 50 Entry (String field, int type) { 51 this.field = field.intern(); 52 this.type = type; 53 this.custom = null; 54 } 55 56 57 Entry (String field, Object custom) { 58 this.field = field.intern(); 59 this.type = SortField.CUSTOM; 60 this.custom = custom; 61 } 62 63 64 public boolean equals (Object 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 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 value) { 86 return Integer.parseInt(value); 87 } 88 }; 89 90 private static final FloatParser FLOAT_PARSER = new FloatParser() { 91 public float parseFloat(String value) { 92 return Float.parseFloat(value); 93 } 94 }; 95 96 97 final Map cache = new WeakHashMap (); 98 99 100 Object lookup (IndexReader reader, String field, int type) { 101 Entry entry = new Entry (field, type); 102 synchronized (this) { 103 HashMap readerCache = (HashMap )cache.get(reader); 104 if (readerCache == null) return null; 105 return readerCache.get (entry); 106 } 107 } 108 109 110 Object lookup (IndexReader reader, String field, Object comparer) { 111 Entry entry = new Entry (field, comparer); 112 synchronized (this) { 113 HashMap readerCache = (HashMap )cache.get(reader); 114 if (readerCache == null) return null; 115 return readerCache.get (entry); 116 } 117 } 118 119 120 Object store (IndexReader reader, String field, int type, Object value) { 121 Entry entry = new Entry (field, type); 122 synchronized (this) { 123 HashMap readerCache = (HashMap )cache.get(reader); 124 if (readerCache == null) { 125 readerCache = new HashMap (); 126 cache.put(reader,readerCache); 127 } 128 return readerCache.put (entry, value); 129 } 130 } 131 132 133 Object store (IndexReader reader, String field, Object comparer, Object value) { 134 Entry entry = new Entry (field, comparer); 135 synchronized (this) { 136 HashMap readerCache = (HashMap )cache.get(reader); 137 if (readerCache == null) { 138 readerCache = new HashMap (); 139 cache.put(reader, readerCache); 140 } 141 return readerCache.put (entry, value); 142 } 143 } 144 145 public int[] getInts (IndexReader reader, String field) throws IOException { 147 return getInts(reader, field, INT_PARSER); 148 } 149 150 public int[] getInts (IndexReader reader, String field, IntParser parser) 152 throws IOException { 153 field = field.intern(); 154 Object 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 public float[] getFloats (IndexReader reader, String field) 181 throws IOException { 182 return getFloats(reader, field, FLOAT_PARSER); 183 } 184 185 public float[] getFloats (IndexReader reader, String field, 187 FloatParser parser) throws IOException { 188 field = field.intern(); 189 Object 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 public String [] getStrings (IndexReader reader, String field) 216 throws IOException { 217 field = field.intern(); 218 Object ret = lookup (reader, field, SortField.STRING); 219 if (ret == null) { 220 final String [] retArray = new String [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 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 []) ret; 241 } 242 243 public StringIndex getStringIndex (IndexReader reader, String field) 245 throws IOException { 246 field = field.intern(); 247 Object ret = lookup (reader, field, STRING_INDEX); 248 if (ret == null) { 249 final int[] retArray = new int[reader.maxDoc()]; 250 String [] mterms = new String [reader.maxDoc()+1]; 251 TermDocs termDocs = reader.termDocs(); 252 TermEnum termEnum = reader.terms (new Term (field, "")); 253 int t = 0; 255 mterms[t++] = null; 260 261 try { 262 do { 263 Term term = termEnum.term(); 264 if (term==null || term.field() != field) break; 265 266 if (t >= mterms.length) throw new RuntimeException ("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 mterms = new String [1]; 289 } else if (t < mterms.length) { 290 String [] terms = new String [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 305 308 309 310 314 315 public Object getAuto (IndexReader reader, String field) 317 throws IOException { 318 field = field.intern(); 319 Object 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 ("no terms in field " + field + " - cannot determine sort type"); 326 } 327 if (term.field() == field) { 328 String termtext = term.text().trim(); 329 330 339 340 try { 342 Integer.parseInt (termtext); 343 ret = getInts (reader, field); 344 } catch (NumberFormatException nfe1) { 345 try { 346 Float.parseFloat (termtext); 347 ret = getFloats (reader, field); 348 } catch (NumberFormatException 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 ("field \"" + field + "\" does not appear to be indexed"); 357 } 358 } finally { 359 enumerator.close(); 360 } 361 362 } 363 return ret; 364 } 365 366 public Comparable [] getCustom (IndexReader reader, String field, SortComparator comparator) 368 throws IOException { 369 field = field.intern(); 370 Object ret = lookup (reader, field, comparator); 371 if (ret == null) { 372 final Comparable [] retArray = new Comparable [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 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 []) ret; 393 } 394 395 } 396 397 | Popular Tags |