Clover coverage report - lucene-core-2.2.0
Coverage timestamp: Mon Jun 18 2007 18:51:12 PDT
file stats: LOC: 509   Methods: 29
NCLOC: 378   Classes: 4
 
 Source file Conditionals Statements Methods TOTAL
FieldCacheImpl.java 82.1% 97.6% 100% 94%
coverage coverage
 1    package org.apache.lucene.search;
 2   
 3    /**
 4    * Licensed to the Apache Software Foundation (ASF) under one or more
 5    * contributor license agreements. See the NOTICE file distributed with
 6    * this work for additional information regarding copyright ownership.
 7    * The ASF licenses this file to You under the Apache License, Version 2.0
 8    * (the "License"); you may not use this file except in compliance with
 9    * the License. You may obtain a copy of the License at
 10    *
 11    * http://www.apache.org/licenses/LICENSE-2.0
 12    *
 13    * Unless required by applicable law or agreed to in writing, software
 14    * distributed under the License is distributed on an "AS IS" BASIS,
 15    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 16    * See the License for the specific language governing permissions and
 17    * limitations under the License.
 18    */
 19   
 20    import org.apache.lucene.index.IndexReader;
 21    import org.apache.lucene.index.Term;
 22    import org.apache.lucene.index.TermDocs;
 23    import org.apache.lucene.index.TermEnum;
 24   
 25    import java.io.IOException;
 26    import java.util.Locale;
 27    import java.util.Map;
 28    import java.util.WeakHashMap;
 29    import java.util.HashMap;
 30   
 31    /**
 32    * Expert: The default cache implementation, storing all values in memory.
 33    * A WeakHashMap is used for storage.
 34    *
 35    * <p>Created: May 19, 2004 4:40:36 PM
 36    *
 37    * @author Tim Jones (Nacimiento Software)
 38    * @since lucene 1.4
 39    * @version $Id: FieldCacheImpl.java 544546 2007-06-05 16:29:35Z doronc $
 40    */
 41    class FieldCacheImpl
 42    implements FieldCache {
 43   
 44    /** Expert: Internal cache. */
 45    abstract static class Cache {
 46    private final Map readerCache = new WeakHashMap();
 47   
 48    protected abstract Object createValue(IndexReader reader, Object key)
 49    throws IOException;
 50   
 51  9888 public Object get(IndexReader reader, Object key) throws IOException {
 52  9888 Map innerCache;
 53  9888 Object value;
 54  9888 synchronized (readerCache) {
 55  9888 innerCache = (Map) readerCache.get(reader);
 56  9888 if (innerCache == null) {
 57  134 innerCache = new HashMap();
 58  134 readerCache.put(reader, innerCache);
 59  134 value = null;
 60    } else {
 61  9754 value = innerCache.get(key);
 62    }
 63  9888 if (value == null) {
 64  218 value = new CreationPlaceholder();
 65  218 innerCache.put(key, value);
 66    }
 67    }
 68  9888 if (value instanceof CreationPlaceholder) {
 69  218 synchronized (value) {
 70  218 CreationPlaceholder progress = (CreationPlaceholder) value;
 71  218 if (progress.value == null) {
 72  218 progress.value = createValue(reader, key);
 73  218 synchronized (readerCache) {
 74  218 innerCache.put(key, progress.value);
 75    }
 76    }
 77  218 return progress.value;
 78    }
 79    }
 80  9670 return value;
 81    }
 82    }
 83   
 84    static final class CreationPlaceholder {
 85    Object value;
 86    }
 87   
 88    /** Expert: Every composite-key in the internal cache is of this type. */
 89    static class Entry {
 90    final String field; // which Fieldable
 91    final int type; // which SortField type
 92    final Object custom; // which custom comparator
 93    final Locale locale; // the locale we're sorting (if string)
 94   
 95    /** Creates one of these objects. */
 96  278 Entry (String field, int type, Locale locale) {
 97  278 this.field = field.intern();
 98  278 this.type = type;
 99  278 this.custom = null;
 100  278 this.locale = locale;
 101    }
 102   
 103    /** Creates one of these objects for a custom comparator. */
 104  9316 Entry (String field, Object custom) {
 105  9316 this.field = field.intern();
 106  9316 this.type = SortField.CUSTOM;
 107  9316 this.custom = custom;
 108  9316 this.locale = null;
 109    }
 110   
 111    /** Two of these are equal iff they reference the same field and type. */
 112  9449 public boolean equals (Object o) {
 113  9449 if (o instanceof Entry) {
 114  9449 Entry other = (Entry) o;
 115  9449 if (other.field == field && other.type == type) {
 116  9449 if (other.locale == null ? locale == null : other.locale.equals(locale)) {
 117  9449 if (other.custom == null) {
 118  205 if (custom == null) return true;
 119  9244 } else if (other.custom.equals (custom)) {
 120  9244 return true;
 121    }
 122    }
 123    }
 124    }
 125  0 return false;
 126    }
 127   
 128    /** Composes a hashcode based on the field and type. */
 129  9797 public int hashCode() {
 130  9797 return field.hashCode() ^ type ^ (custom==null ? 0 : custom.hashCode()) ^ (locale==null ? 0 : locale.hashCode());
 131    }
 132    }
 133   
 134    private static final ByteParser BYTE_PARSER = new ByteParser() {
 135  102 public byte parseByte(String value) {
 136  102 return Byte.parseByte(value);
 137    }
 138    };
 139   
 140    private static final ShortParser SHORT_PARSER = new ShortParser() {
 141  102 public short parseShort(String value) {
 142  102 return Short.parseShort(value);
 143    }
 144    };
 145   
 146    private static final IntParser INT_PARSER = new IntParser() {
 147  402 public int parseInt(String value) {
 148  402 return Integer.parseInt(value);
 149    }
 150    };
 151   
 152    private static final FloatParser FLOAT_PARSER = new FloatParser() {
 153  324 public float parseFloat(String value) {
 154  324 return Float.parseFloat(value);
 155    }
 156    };
 157   
 158    // inherit javadocs
 159  1847 public byte[] getBytes (IndexReader reader, String field) throws IOException {
 160  1847 return getBytes(reader, field, BYTE_PARSER);
 161    }
 162   
 163    // inherit javadocs
 164  1847 public byte[] getBytes(IndexReader reader, String field, ByteParser parser)
 165    throws IOException {
 166  1847 return (byte[]) bytesCache.get(reader, new Entry(field, parser));
 167    }
 168   
 169    Cache bytesCache = new Cache() {
 170   
 171  6 protected Object createValue(IndexReader reader, Object entryKey)
 172    throws IOException {
 173  6 Entry entry = (Entry) entryKey;
 174  6 String field = entry.field;
 175  6 ByteParser parser = (ByteParser) entry.custom;
 176  6 final byte[] retArray = new byte[reader.maxDoc()];
 177  6 TermDocs termDocs = reader.termDocs();
 178  6 TermEnum termEnum = reader.terms (new Term (field, ""));
 179  6 try {
 180  6 do {
 181  108 Term term = termEnum.term();
 182  6 if (term==null || term.field() != field) break;
 183  102 byte termval = parser.parseByte(term.text());
 184  102 termDocs.seek (termEnum);
 185  102 while (termDocs.next()) {
 186  102 retArray[termDocs.doc()] = termval;
 187    }
 188  102 } while (termEnum.next());
 189    } finally {
 190  6 termDocs.close();
 191  6 termEnum.close();
 192    }
 193  6 return retArray;
 194    }
 195    };
 196   
 197    // inherit javadocs
 198  1847 public short[] getShorts (IndexReader reader, String field) throws IOException {
 199  1847 return getShorts(reader, field, SHORT_PARSER);
 200    }
 201   
 202    // inherit javadocs
 203  1847 public short[] getShorts(IndexReader reader, String field, ShortParser parser)
 204    throws IOException {
 205  1847 return (short[]) shortsCache.get(reader, new Entry(field, parser));
 206    }
 207   
 208    Cache shortsCache = new Cache() {
 209   
 210  6 protected Object createValue(IndexReader reader, Object entryKey)
 211    throws IOException {
 212  6 Entry entry = (Entry) entryKey;
 213  6 String field = entry.field;
 214  6 ShortParser parser = (ShortParser) entry.custom;
 215  6 final short[] retArray = new short[reader.maxDoc()];
 216  6 TermDocs termDocs = reader.termDocs();
 217  6 TermEnum termEnum = reader.terms (new Term (field, ""));
 218  6 try {
 219  6 do {
 220  108 Term term = termEnum.term();
 221  6 if (term==null || term.field() != field) break;
 222  102 short termval = parser.parseShort(term.text());
 223  102 termDocs.seek (termEnum);
 224  102 while (termDocs.next()) {
 225  102 retArray[termDocs.doc()] = termval;
 226    }
 227  102 } while (termEnum.next());
 228    } finally {
 229  6 termDocs.close();
 230  6 termEnum.close();
 231    }
 232  6 return retArray;
 233    }
 234    };
 235   
 236    // inherit javadocs
 237  1886 public int[] getInts (IndexReader reader, String field) throws IOException {
 238  1886 return getInts(reader, field, INT_PARSER);
 239    }
 240   
 241    // inherit javadocs
 242  1886 public int[] getInts(IndexReader reader, String field, IntParser parser)
 243    throws IOException {
 244  1886 return (int[]) intsCache.get(reader, new Entry(field, parser));
 245    }
 246   
 247    Cache intsCache = new Cache() {
 248   
 249  24 protected Object createValue(IndexReader reader, Object entryKey)
 250    throws IOException {
 251  24 Entry entry = (Entry) entryKey;
 252  24 String field = entry.field;
 253  24 IntParser parser = (IntParser) entry.custom;
 254  24 final int[] retArray = new int[reader.maxDoc()];
 255  24 TermDocs termDocs = reader.termDocs();
 256  24 TermEnum termEnum = reader.terms (new Term (field, ""));
 257  24 try {
 258  24 do {
 259  422 Term term = termEnum.term();
 260  20 if (term==null || term.field() != field) break;
 261  402 int termval = parser.parseInt(term.text());
 262  402 termDocs.seek (termEnum);
 263  402 while (termDocs.next()) {
 264  6632 retArray[termDocs.doc()] = termval;
 265    }
 266  402 } while (termEnum.next());
 267    } finally {
 268  24 termDocs.close();
 269  24 termEnum.close();
 270    }
 271  24 return retArray;
 272    }
 273    };
 274   
 275    // inherit javadocs
 276  3725 public float[] getFloats (IndexReader reader, String field)
 277    throws IOException {
 278  3725 return getFloats(reader, field, FLOAT_PARSER);
 279    }
 280   
 281    // inherit javadocs
 282  3725 public float[] getFloats(IndexReader reader, String field, FloatParser parser)
 283    throws IOException {
 284  3725 return (float[]) floatsCache.get(reader, new Entry(field, parser));
 285    }
 286   
 287    Cache floatsCache = new Cache() {
 288   
 289  26 protected Object createValue(IndexReader reader, Object entryKey)
 290    throws IOException {
 291  26 Entry entry = (Entry) entryKey;
 292  26 String field = entry.field;
 293  26 FloatParser parser = (FloatParser) entry.custom;
 294  26 final float[] retArray = new float[reader.maxDoc()];
 295  26 TermDocs termDocs = reader.termDocs();
 296  26 TermEnum termEnum = reader.terms (new Term (field, ""));
 297  26 try {
 298  26 do {
 299  350 Term term = termEnum.term();
 300  26 if (term==null || term.field() != field) break;
 301  324 float termval = parser.parseFloat(term.text());
 302  324 termDocs.seek (termEnum);
 303  324 while (termDocs.next()) {
 304  324 retArray[termDocs.doc()] = termval;
 305    }
 306  324 } while (termEnum.next());
 307    } finally {
 308  26 termDocs.close();
 309  26 termEnum.close();
 310    }
 311  26 return retArray;
 312    }
 313    };
 314   
 315    // inherit javadocs
 316  14 public String[] getStrings(IndexReader reader, String field)
 317    throws IOException {
 318  14 return (String[]) stringsCache.get(reader, field);
 319    }
 320   
 321    Cache stringsCache = new Cache() {
 322   
 323  9 protected Object createValue(IndexReader reader, Object fieldKey)
 324    throws IOException {
 325  9 String field = ((String) fieldKey).intern();
 326  9 final String[] retArray = new String[reader.maxDoc()];
 327  9 TermDocs termDocs = reader.termDocs();
 328  9 TermEnum termEnum = reader.terms (new Term (field, ""));
 329  9 try {
 330  9 do {
 331  73 Term term = termEnum.term();
 332  3 if (term==null || term.field() != field) break;
 333  70 String termval = term.text();
 334  70 termDocs.seek (termEnum);
 335  70 while (termDocs.next()) {
 336  70 retArray[termDocs.doc()] = termval;
 337    }
 338  70 } while (termEnum.next());
 339    } finally {
 340  9 termDocs.close();
 341  9 termEnum.close();
 342    }
 343  9 return retArray;
 344    }
 345    };
 346   
 347    // inherit javadocs
 348  239 public StringIndex getStringIndex(IndexReader reader, String field)
 349    throws IOException {
 350  239 return (StringIndex) stringsIndexCache.get(reader, field);
 351    }
 352   
 353    Cache stringsIndexCache = new Cache() {
 354   
 355  23 protected Object createValue(IndexReader reader, Object fieldKey)
 356    throws IOException {
 357  23 String field = ((String) fieldKey).intern();
 358  23 final int[] retArray = new int[reader.maxDoc()];
 359  23 String[] mterms = new String[reader.maxDoc()+1];
 360  23 TermDocs termDocs = reader.termDocs();
 361  23 TermEnum termEnum = reader.terms (new Term (field, ""));
 362  23 int t = 0; // current term number
 363   
 364    // an entry for documents that have no terms in this field
 365    // should a document with no terms be at top or bottom?
 366    // this puts them at the top - if it is changed, FieldDocSortedHitQueue
 367    // needs to change as well.
 368  23 mterms[t++] = null;
 369   
 370  23 try {
 371  23 do {
 372  232 Term term = termEnum.term();
 373  9 if (term==null || term.field() != field) break;
 374   
 375    // store term text
 376    // we expect that there is at most one term per document
 377  0 if (t >= mterms.length) throw new RuntimeException ("there are more terms than " +
 378    "documents in field \"" + field + "\", but it's impossible to sort on " +
 379    "tokenized fields");
 380  223 mterms[t] = term.text();
 381   
 382  223 termDocs.seek (termEnum);
 383  223 while (termDocs.next()) {
 384  223 retArray[termDocs.doc()] = t;
 385    }
 386   
 387  223 t++;
 388  223 } while (termEnum.next());
 389    } finally {
 390  23 termDocs.close();
 391  23 termEnum.close();
 392    }
 393   
 394  23 if (t == 0) {
 395    // if there are no terms, make the term array
 396    // have a single null entry
 397  0 mterms = new String[1];
 398  23 } else if (t < mterms.length) {
 399    // if there are less terms than documents,
 400    // trim off the dead array space
 401  14 String[] terms = new String[t];
 402  14 System.arraycopy (mterms, 0, terms, 0, t);
 403  14 mterms = terms;
 404    }
 405   
 406  23 StringIndex value = new StringIndex (retArray, mterms);
 407  23 return value;
 408    }
 409    };
 410   
 411    /** The pattern used to detect integer values in a field */
 412    /** removed for java 1.3 compatibility
 413    protected static final Pattern pIntegers = Pattern.compile ("[0-9\\-]+");
 414    **/
 415   
 416    /** The pattern used to detect float values in a field */
 417    /**
 418    * removed for java 1.3 compatibility
 419    * protected static final Object pFloats = Pattern.compile ("[0-9+\\-\\.eEfFdD]+");
 420    */
 421   
 422    // inherit javadocs
 423  41 public Object getAuto(IndexReader reader, String field) throws IOException {
 424  41 return autoCache.get(reader, field);
 425    }
 426   
 427    Cache autoCache = new Cache() {
 428   
 429  41 protected Object createValue(IndexReader reader, Object fieldKey)
 430    throws IOException {
 431  41 String field = ((String)fieldKey).intern();
 432  41 TermEnum enumerator = reader.terms (new Term (field, ""));
 433  41 try {
 434  41 Term term = enumerator.term();
 435  41 if (term == null) {
 436  0 throw new RuntimeException ("no terms in field " + field + " - cannot determine sort type");
 437    }
 438  41 Object ret = null;
 439  41 if (term.field() == field) {
 440  41 String termtext = term.text().trim();
 441   
 442    /**
 443    * Java 1.4 level code:
 444