Index: solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java =================================================================== --- solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java (revision 1511552) +++ solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java (working copy) @@ -601,40 +601,44 @@ } getIndexReader().document(n, visitor); } - + /** Executes a stored field visitor against a hit from the document cache */ private void visitFromCached(StoredDocument document, StoredFieldVisitor visitor) throws IOException { - for (StorableField f : document) { - FieldInfo info = fieldInfos.fieldInfo(f.name()); - switch(visitor.needsField(info)) { - case YES: - if (f.binaryValue() != null) { - BytesRef binaryValue = f.binaryValue(); - byte copy[] = new byte[binaryValue.length]; - System.arraycopy(binaryValue.bytes, binaryValue.offset, copy, 0, copy.length); - visitor.binaryField(info, copy); - } else if (f.numericValue() != null) { - Number numericValue = f.numericValue(); - if (numericValue instanceof Double) { - visitor.doubleField(info, numericValue.doubleValue()); - } else if (numericValue instanceof Integer) { - visitor.intField(info, numericValue.intValue()); - } else if (numericValue instanceof Float) { - visitor.floatField(info, numericValue.floatValue()); - } else if (numericValue instanceof Long) { - visitor.longField(info, numericValue.longValue()); + try { + for (StorableField f : document) { + FieldInfo info = fieldInfos.fieldInfo(f.name()); + switch(visitor.needsField(info)) { + case YES: + if (f.binaryValue() != null) { + BytesRef binaryValue = f.binaryValue(); + byte copy[] = new byte[binaryValue.length]; + System.arraycopy(binaryValue.bytes, binaryValue.offset, copy, 0, copy.length); + visitor.binaryField(info, copy); + } else if (f.numericValue() != null) { + Number numericValue = f.numericValue(); + if (numericValue instanceof Double) { + visitor.doubleField(info, numericValue.doubleValue()); + } else if (numericValue instanceof Integer) { + visitor.intField(info, numericValue.intValue()); + } else if (numericValue instanceof Float) { + visitor.floatField(info, numericValue.floatValue()); + } else if (numericValue instanceof Long) { + visitor.longField(info, numericValue.longValue()); + } else { + throw new AssertionError(); + } } else { - throw new AssertionError(); + visitor.stringField(info, f.stringValue()); } - } else { - visitor.stringField(info, f.stringValue()); - } - break; - case NO: - break; - case STOP: - return; + break; + case NO: + break; + case STOP: + return; + } } + } finally { + visitor.reset(); } } Index: lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40StoredFieldsReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40StoredFieldsReader.java (revision 1511552) +++ lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40StoredFieldsReader.java (working copy) @@ -147,23 +147,27 @@ fieldsStream.seek(indexStream.readLong()); final int numFields = fieldsStream.readVInt(); - for (int fieldIDX = 0; fieldIDX < numFields; fieldIDX++) { - int fieldNumber = fieldsStream.readVInt(); - FieldInfo fieldInfo = fieldInfos.fieldInfo(fieldNumber); - - int bits = fieldsStream.readByte() & 0xFF; - assert bits <= (FIELD_IS_NUMERIC_MASK | FIELD_IS_BINARY): "bits=" + Integer.toHexString(bits); + try { + for (int fieldIDX = 0; fieldIDX < numFields; fieldIDX++) { + int fieldNumber = fieldsStream.readVInt(); + FieldInfo fieldInfo = fieldInfos.fieldInfo(fieldNumber); - switch(visitor.needsField(fieldInfo)) { - case YES: - readField(visitor, fieldInfo, bits); - break; - case NO: - skipField(bits); - break; - case STOP: - return; + int bits = fieldsStream.readByte() & 0xFF; + assert bits <= (FIELD_IS_NUMERIC_MASK | FIELD_IS_BINARY): "bits=" + Integer.toHexString(bits); + + switch(visitor.needsField(fieldInfo)) { + case YES: + readField(visitor, fieldInfo, bits); + break; + case NO: + skipField(bits); + break; + case STOP: + return; + } } + } finally { + visitor.reset(); } } Index: lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingStoredFieldsReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingStoredFieldsReader.java (revision 1511552) +++ lucene/core/src/java/org/apache/lucene/codecs/compressing/CompressingStoredFieldsReader.java (working copy) @@ -266,26 +266,30 @@ assert bytes.length == length; final ByteArrayDataInput documentInput = new ByteArrayDataInput(bytes.bytes, bytes.offset, bytes.length); - for (int fieldIDX = 0; fieldIDX < numStoredFields; fieldIDX++) { - final long infoAndBits = documentInput.readVLong(); - final int fieldNumber = (int) (infoAndBits >>> TYPE_BITS); - final FieldInfo fieldInfo = fieldInfos.fieldInfo(fieldNumber); + try { + for (int fieldIDX = 0; fieldIDX < numStoredFields; fieldIDX++) { + final long infoAndBits = documentInput.readVLong(); + final int fieldNumber = (int) (infoAndBits >>> TYPE_BITS); + final FieldInfo fieldInfo = fieldInfos.fieldInfo(fieldNumber); - final int bits = (int) (infoAndBits & TYPE_MASK); - assert bits <= NUMERIC_DOUBLE: "bits=" + Integer.toHexString(bits); + final int bits = (int) (infoAndBits & TYPE_MASK); + assert bits <= NUMERIC_DOUBLE: "bits=" + Integer.toHexString(bits); - switch(visitor.needsField(fieldInfo)) { - case YES: - readField(documentInput, visitor, fieldInfo, bits); - assert documentInput.getPosition() <= bytes.offset + bytes.length : documentInput.getPosition() + " " + bytes.offset + bytes.length; - break; - case NO: - skipField(documentInput, bits); - assert documentInput.getPosition() <= bytes.offset + bytes.length : documentInput.getPosition() + " " + bytes.offset + bytes.length; - break; - case STOP: - return; + switch(visitor.needsField(fieldInfo)) { + case YES: + readField(documentInput, visitor, fieldInfo, bits); + assert documentInput.getPosition() <= bytes.offset + bytes.length : documentInput.getPosition() + " " + bytes.offset + bytes.length; + break; + case NO: + skipField(documentInput, bits); + assert documentInput.getPosition() <= bytes.offset + bytes.length : documentInput.getPosition() + " " + bytes.offset + bytes.length; + break; + case STOP: + return; + } } + } finally { + visitor.reset(); } assert documentInput.getPosition() == bytes.offset + bytes.length : documentInput.getPosition() + " " + bytes.offset + " " + bytes.length; } Index: lucene/core/src/java/org/apache/lucene/index/StoredFieldVisitor.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/StoredFieldVisitor.java (revision 1511552) +++ lucene/core/src/java/org/apache/lucene/index/StoredFieldVisitor.java (working copy) @@ -81,7 +81,11 @@ * entirely. */ public abstract Status needsField(FieldInfo fieldInfo) throws IOException; - + + /** Reset the visitor after a document's fields have been visited */ + public void reset() { + } + /** * Enumeration of possible return values for {@link #needsField}. */ Index: lucene/highlighter/src/java/org/apache/lucene/search/postingshighlight/PostingsHighlighter.java =================================================================== --- lucene/highlighter/src/java/org/apache/lucene/search/postingshighlight/PostingsHighlighter.java (revision 1511552) +++ lucene/highlighter/src/java/org/apache/lucene/search/postingshighlight/PostingsHighlighter.java (working copy) @@ -379,7 +379,7 @@ for (int j = 0; j < fields.length; j++) { contents[j][i] = visitor.getValue(j).toString(); } - visitor.reset(); + visitor.resetState(); } return contents; } @@ -710,8 +710,8 @@ String getValue(int i) { return builders[i].toString(); } - - void reset() { + + public void resetState() { currentField = -1; for (int i = 0; i < fields.length; i++) { builders[i].setLength(0); Index: lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsReader.java =================================================================== --- lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsReader.java (revision 1511552) +++ lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsReader.java (working copy) @@ -96,44 +96,48 @@ readLine(); assert StringHelper.startsWith(scratch, NUM); int numFields = parseIntAt(NUM.length); - - for (int i = 0; i < numFields; i++) { - readLine(); - assert StringHelper.startsWith(scratch, FIELD); - int fieldNumber = parseIntAt(FIELD.length); - FieldInfo fieldInfo = fieldInfos.fieldInfo(fieldNumber); - readLine(); - assert StringHelper.startsWith(scratch, NAME); - readLine(); - assert StringHelper.startsWith(scratch, TYPE); - - final BytesRef type; - if (equalsAt(TYPE_STRING, scratch, TYPE.length)) { - type = TYPE_STRING; - } else if (equalsAt(TYPE_BINARY, scratch, TYPE.length)) { - type = TYPE_BINARY; - } else if (equalsAt(TYPE_INT, scratch, TYPE.length)) { - type = TYPE_INT; - } else if (equalsAt(TYPE_LONG, scratch, TYPE.length)) { - type = TYPE_LONG; - } else if (equalsAt(TYPE_FLOAT, scratch, TYPE.length)) { - type = TYPE_FLOAT; - } else if (equalsAt(TYPE_DOUBLE, scratch, TYPE.length)) { - type = TYPE_DOUBLE; - } else { - throw new RuntimeException("unknown field type"); + + try { + for (int i = 0; i < numFields; i++) { + readLine(); + assert StringHelper.startsWith(scratch, FIELD); + int fieldNumber = parseIntAt(FIELD.length); + FieldInfo fieldInfo = fieldInfos.fieldInfo(fieldNumber); + readLine(); + assert StringHelper.startsWith(scratch, NAME); + readLine(); + assert StringHelper.startsWith(scratch, TYPE); + + final BytesRef type; + if (equalsAt(TYPE_STRING, scratch, TYPE.length)) { + type = TYPE_STRING; + } else if (equalsAt(TYPE_BINARY, scratch, TYPE.length)) { + type = TYPE_BINARY; + } else if (equalsAt(TYPE_INT, scratch, TYPE.length)) { + type = TYPE_INT; + } else if (equalsAt(TYPE_LONG, scratch, TYPE.length)) { + type = TYPE_LONG; + } else if (equalsAt(TYPE_FLOAT, scratch, TYPE.length)) { + type = TYPE_FLOAT; + } else if (equalsAt(TYPE_DOUBLE, scratch, TYPE.length)) { + type = TYPE_DOUBLE; + } else { + throw new RuntimeException("unknown field type"); + } + + switch (visitor.needsField(fieldInfo)) { + case YES: + readField(type, fieldInfo, visitor); + break; + case NO: + readLine(); + assert StringHelper.startsWith(scratch, VALUE); + break; + case STOP: return; + } } - - switch (visitor.needsField(fieldInfo)) { - case YES: - readField(type, fieldInfo, visitor); - break; - case NO: - readLine(); - assert StringHelper.startsWith(scratch, VALUE); - break; - case STOP: return; - } + } finally { + visitor.reset(); } } Index: lucene/test-framework/src/java/org/apache/lucene/index/FieldFilterAtomicReader.java =================================================================== --- lucene/test-framework/src/java/org/apache/lucene/index/FieldFilterAtomicReader.java (revision 1511552) +++ lucene/test-framework/src/java/org/apache/lucene/index/FieldFilterAtomicReader.java (working copy) @@ -105,6 +105,11 @@ public Status needsField(FieldInfo fieldInfo) throws IOException { return hasField(fieldInfo.name) ? visitor.needsField(fieldInfo) : Status.NO; } + + @Override + public void reset() { + visitor.reset(); + } }); }