Index: lucene/core/src/java/org/apache/lucene/codecs/DocValuesConsumer.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/DocValuesConsumer.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/codecs/DocValuesConsumer.java (working copy) @@ -28,20 +28,22 @@ import org.apache.lucene.document.PackedLongDocValuesField; import org.apache.lucene.document.ShortDocValuesField; import org.apache.lucene.document.SortedBytesDocValuesField; +import org.apache.lucene.document.StoredField; import org.apache.lucene.document.StraightBytesDocValuesField; import org.apache.lucene.index.DocValues.Source; import org.apache.lucene.index.DocValues.Type; import org.apache.lucene.index.DocValues; import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.StorableField; import org.apache.lucene.index.MergeState; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; /** - * Abstract API that consumes {@link IndexableField}s. + * Abstract API that consumes {@link StorableField}s. * {@link DocValuesConsumer} are always associated with a specific field and * segments. Concrete implementations of this API write the given - * {@link IndexableField} into a implementation specific format depending on + * {@link StorableField} into a implementation specific format depending on * the fields meta-data. * * @lucene.experimental @@ -52,7 +54,7 @@ protected abstract Type getType(); /** - * Adds the given {@link IndexableField} instance to this + * Adds the given {@link StorableField} instance to this * {@link DocValuesConsumer} * * @param docID @@ -63,7 +65,7 @@ * @throws IOException * if an {@link IOException} occurs */ - public abstract void add(int docID, IndexableField value) + public abstract void add(int docID, StorableField value) throws IOException; /** @@ -72,7 +74,7 @@ * @param docCount * the total number of documents in this {@link DocValuesConsumer}. * Must be greater than or equal the last given docID to - * {@link #add(int, IndexableField)}. + * {@link #add(int, StorableField)}. * @throws IOException */ public abstract void finish(int docCount) throws IOException; @@ -122,7 +124,7 @@ assert source != null; int docID = docBase; final Type type = getType(); - final Field scratchField; + final StoredField scratchField; switch(type) { case VAR_INTS: scratchField = new PackedLongDocValuesField("", (long) 0); @@ -188,7 +190,7 @@ * ID must always be greater than the previous ID or 0 if called the * first time. */ - protected void mergeDoc(Field scratchField, Source source, int docID, int sourceDoc) + protected void mergeDoc(StoredField scratchField, Source source, int docID, int sourceDoc) throws IOException { switch(getType()) { case BYTES_FIXED_DEREF: Index: lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40StoredFieldsWriter.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40StoredFieldsWriter.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40StoredFieldsWriter.java (working copy) @@ -21,6 +21,7 @@ import org.apache.lucene.codecs.StoredFieldsReader; import org.apache.lucene.codecs.StoredFieldsWriter; import org.apache.lucene.document.Document; +import org.apache.lucene.document.StoredDocument; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.IndexFileNames; @@ -28,6 +29,7 @@ import org.apache.lucene.index.MergePolicy.MergeAbortedException; import org.apache.lucene.index.MergeState; import org.apache.lucene.index.SegmentReader; +import org.apache.lucene.index.StorableField; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexInput; @@ -131,7 +133,7 @@ IndexFileNames.segmentFileName(segment, "", FIELDS_INDEX_EXTENSION)); } - public void writeField(FieldInfo info, IndexableField field) throws IOException { + public void writeField(FieldInfo info, StorableField field) throws IOException { fieldsStream.writeVInt(info.number); int bits = 0; final BytesRef bytes; @@ -297,7 +299,7 @@ // on the fly? // NOTE: it's very important to first assign to doc then pass it to // fieldsWriter.addDocument; see LUCENE-1282 - Document doc = reader.reader.document(j); + StoredDocument doc = reader.reader.document(j); addDocument(doc, mergeState.fieldInfos); docCount++; mergeState.checkAbort.work(300); @@ -324,7 +326,7 @@ for (; docCount < maxDoc; docCount++) { // NOTE: it's very important to first assign to doc then pass it to // fieldsWriter.addDocument; see LUCENE-1282 - Document doc = reader.reader.document(docCount); + StoredDocument doc = reader.reader.document(docCount); addDocument(doc, mergeState.fieldInfos); mergeState.checkAbort.work(300); } Index: lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Bytes.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Bytes.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Bytes.java (working copy) @@ -29,6 +29,7 @@ import org.apache.lucene.index.DocValues; import org.apache.lucene.index.IndexFileNames; import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.StorableField; import org.apache.lucene.store.DataOutput; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; @@ -415,7 +416,7 @@ } @Override - public void add(int docID, IndexableField value) throws IOException { + public void add(int docID, StorableField value) throws IOException { BytesRef bytes = value.binaryValue(); assert bytes != null; if (bytes.length == 0) { // default value - skip it Index: lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedStraightBytesImpl.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedStraightBytesImpl.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/FixedStraightBytesImpl.java (working copy) @@ -22,12 +22,12 @@ import org.apache.lucene.codecs.lucene40.values.Bytes.BytesReaderBase; import org.apache.lucene.codecs.lucene40.values.Bytes.BytesSourceBase; import org.apache.lucene.codecs.lucene40.values.Bytes.BytesWriterBase; +import org.apache.lucene.document.StoredField; import org.apache.lucene.document.StraightBytesDocValuesField; -import org.apache.lucene.document.Field; import org.apache.lucene.index.DocValues.Source; import org.apache.lucene.index.DocValues.Type; import org.apache.lucene.index.DocValues; -import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.StorableField; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexInput; @@ -74,7 +74,7 @@ } @Override - public void add(int docID, IndexableField value) throws IOException { + public void add(int docID, StorableField value) throws IOException { final BytesRef bytes = value.binaryValue(); assert bytes != null; assert lastDocID < docID; @@ -196,7 +196,7 @@ } @Override - protected void mergeDoc(Field scratchField, Source source, int docID, int sourceDoc) throws IOException { + protected void mergeDoc(StoredField scratchField, Source source, int docID, int sourceDoc) throws IOException { assert lastDocID < docID; setMergeBytes(source, sourceDoc); if (size == -1) { Index: lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Floats.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Floats.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Floats.java (working copy) @@ -24,6 +24,7 @@ import org.apache.lucene.index.DocValues.Type; import org.apache.lucene.index.DocValues; import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.StorableField; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexInput; @@ -88,7 +89,7 @@ } @Override - public void add(int docID, IndexableField value) throws IOException { + public void add(int docID, StorableField value) throws IOException { template.toBytes(value.numericValue().doubleValue(), bytesRef); bytesSpareField.setBytesValue(bytesRef); super.add(docID, bytesSpareField); Index: lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Ints.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Ints.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/Ints.java (working copy) @@ -25,6 +25,7 @@ import org.apache.lucene.index.DocValues.Type; import org.apache.lucene.index.DocValues; import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.StorableField; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexInput; @@ -112,7 +113,7 @@ } @Override - public void add(int docID, IndexableField value) throws IOException { + public void add(int docID, StorableField value) throws IOException { template.toBytes(value.numericValue().longValue(), bytesRef); bytesSpareField.setBytesValue(bytesRef); super.add(docID, bytesSpareField); Index: lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/PackedIntValues.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/PackedIntValues.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/PackedIntValues.java (working copy) @@ -25,6 +25,7 @@ import org.apache.lucene.index.DocValues; import org.apache.lucene.index.IndexFileNames; import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.StorableField; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexInput; @@ -126,7 +127,7 @@ } @Override - public void add(int docID, IndexableField docValue) throws IOException { + public void add(int docID, StorableField docValue) throws IOException { final long v = docValue.numericValue().longValue(); assert lastDocId < docID; if (!started) { Index: lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarStraightBytesImpl.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarStraightBytesImpl.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/codecs/lucene40/values/VarStraightBytesImpl.java (working copy) @@ -22,11 +22,11 @@ import org.apache.lucene.codecs.lucene40.values.Bytes.BytesReaderBase; import org.apache.lucene.codecs.lucene40.values.Bytes.BytesSourceBase; import org.apache.lucene.codecs.lucene40.values.Bytes.BytesWriterBase; -import org.apache.lucene.document.Field; +import org.apache.lucene.document.StoredField; import org.apache.lucene.index.DocValues.Source; import org.apache.lucene.index.DocValues.Type; import org.apache.lucene.index.DocValues; -import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.StorableField; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexInput; @@ -85,7 +85,7 @@ } @Override - public void add(int docID, IndexableField value) throws IOException { + public void add(int docID, StorableField value) throws IOException { final BytesRef bytes = value.binaryValue(); assert bytes != null; assert !merge; @@ -155,7 +155,7 @@ } @Override - protected void mergeDoc(Field scratchField, Source source, int docID, int sourceDoc) throws IOException { + protected void mergeDoc(StoredField scratchField, Source source, int docID, int sourceDoc) throws IOException { assert merge; assert lastDocID < docID; source.getBytes(sourceDoc, bytesRef); Index: lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextDocValuesConsumer.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextDocValuesConsumer.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextDocValuesConsumer.java (working copy) @@ -21,7 +21,7 @@ import org.apache.lucene.codecs.DocValuesConsumer; import org.apache.lucene.index.DocValues.Type; import org.apache.lucene.index.IndexFileNames; -import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.StorableField; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexOutput; @@ -72,7 +72,7 @@ } @Override - public void add(int docID, IndexableField value) throws IOException { + public void add(int docID, StorableField value) throws IOException { assert docID >= 0; final int ord, vSize; switch (type) { Index: lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsWriter.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsWriter.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsWriter.java (working copy) @@ -22,7 +22,7 @@ import org.apache.lucene.codecs.StoredFieldsWriter; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.IndexFileNames; -import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.StorableField; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexOutput; @@ -88,7 +88,7 @@ } @Override - public void writeField(FieldInfo info, IndexableField field) throws IOException { + public void writeField(FieldInfo info, StorableField field) throws IOException { write(FIELD); write(Integer.toString(info.number)); newLine(); Index: lucene/core/src/java/org/apache/lucene/codecs/StoredFieldsWriter.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/StoredFieldsWriter.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/codecs/StoredFieldsWriter.java (working copy) @@ -4,10 +4,12 @@ import java.io.IOException; import org.apache.lucene.document.Document; +import org.apache.lucene.document.StoredDocument; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.FieldInfos; import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.MergeState; +import org.apache.lucene.index.StorableField; import org.apache.lucene.util.Bits; /** @@ -32,7 +34,7 @@ *
    *
  1. For every document, {@link #startDocument(int)} is called, * informing the Codec how many fields will be written. - *
  2. {@link #writeField(FieldInfo, IndexableField)} is called for + *
  3. {@link #writeField(FieldInfo, StorableField)} is called for * each field in the document. *
  4. After all documents have been written, {@link #finish(int)} * is called for verification/sanity-checks. @@ -44,14 +46,14 @@ public abstract class StoredFieldsWriter implements Closeable { /** Called before writing the stored fields of the document. - * {@link #writeField(FieldInfo, IndexableField)} will be called + * {@link #writeField(FieldInfo, StorableField)} will be called * numStoredFields times. Note that this is * called even if the document has no stored fields, in * this case numStoredFields will be zero. */ public abstract void startDocument(int numStoredFields) throws IOException; /** Writes a single stored field. */ - public abstract void writeField(FieldInfo info, IndexableField field) throws IOException; + public abstract void writeField(FieldInfo info, StorableField field) throws IOException; /** Aborts writing entirely, implementation should remove * any partially-written files, etc. */ @@ -68,7 +70,7 @@ /** Merges in the stored fields from the readers in * mergeState. The default implementation skips * over deleted documents, and uses {@link #startDocument(int)}, - * {@link #writeField(FieldInfo, IndexableField)}, and {@link #finish(int)}, + * {@link #writeField(FieldInfo, StorableField)}, and {@link #finish(int)}, * returning the number of documents that were written. * Implementations can override this method for more sophisticated * merging (bulk-byte copying, etc). */ @@ -88,7 +90,7 @@ // on the fly? // NOTE: it's very important to first assign to doc then pass it to // fieldsWriter.addDocument; see LUCENE-1282 - Document doc = reader.reader.document(i); + StoredDocument doc = reader.reader.document(i); addDocument(doc, mergeState.fieldInfos); docCount++; mergeState.checkAbort.work(300); @@ -99,20 +101,16 @@ } /** sugar method for startDocument() + writeField() for every stored field in the document */ - protected final void addDocument(Iterable doc, FieldInfos fieldInfos) throws IOException { + protected final void addDocument(Iterable doc, FieldInfos fieldInfos) throws IOException { int storedCount = 0; - for (IndexableField field : doc) { - if (field.fieldType().stored()) { - storedCount++; - } + for (StorableField field : doc) { + storedCount++; } startDocument(storedCount); - for (IndexableField field : doc) { - if (field.fieldType().stored()) { + for (StorableField field : doc) { writeField(fieldInfos.fieldInfo(field.name()), field); - } } } } Index: lucene/core/src/java/org/apache/lucene/document/ByteDocValuesField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/ByteDocValuesField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/ByteDocValuesField.java (working copy) @@ -34,9 +34,9 @@ * separate {@link StoredField} instance. * */ -public class ByteDocValuesField extends Field { +public class ByteDocValuesField extends StoredField { - public static final FieldType TYPE = new FieldType(); + public static final StoredFieldType TYPE = new StoredFieldType(); static { TYPE.setDocValueType(DocValues.Type.FIXED_INTS_8); TYPE.freeze(); Index: lucene/core/src/java/org/apache/lucene/document/DerefBytesDocValuesField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/DerefBytesDocValuesField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/DerefBytesDocValuesField.java (working copy) @@ -39,16 +39,16 @@ * separate {@link StoredField} instance. * */ -public class DerefBytesDocValuesField extends Field { +public class DerefBytesDocValuesField extends StoredField { // TODO: ideally indexer figures out var vs fixed on its own!? - public static final FieldType TYPE_FIXED_LEN = new FieldType(); + public static final StoredFieldType TYPE_FIXED_LEN = new StoredFieldType(); static { TYPE_FIXED_LEN.setDocValueType(DocValues.Type.BYTES_FIXED_DEREF); TYPE_FIXED_LEN.freeze(); } - public static final FieldType TYPE_VAR_LEN = new FieldType(); + public static final StoredFieldType TYPE_VAR_LEN = new StoredFieldType(); static { TYPE_VAR_LEN.setDocValueType(DocValues.Type.BYTES_VAR_DEREF); TYPE_VAR_LEN.freeze(); Index: lucene/core/src/java/org/apache/lucene/document/Document.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/Document.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/Document.java (working copy) @@ -21,6 +21,7 @@ import org.apache.lucene.index.IndexReader; // for javadoc import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.StorableField; import org.apache.lucene.search.IndexSearcher; // for javadoc import org.apache.lucene.search.ScoreDoc; // for javadoc import org.apache.lucene.util.BytesRef; @@ -38,16 +39,16 @@ * ScoreDoc#doc} or {@link IndexReader#document(int)}. */ -public final class Document implements Iterable { +public final class Document implements org.apache.lucene.index.Document{ private final List fields = new ArrayList(); + private final List storedFields = new ArrayList(); /** Constructs a new document with no fields. */ public Document() {} - - @Override - public Iterator iterator() { - return fields.iterator(); + + public Iterator storableIterator() { + return storedFields.iterator(); } /** @@ -64,6 +65,10 @@ fields.add(field); } + public final void add(StorableField field) { + storedFields.add(field); + } + /** *

    Removes field with the specified name from the document. * If multiple fields exist with this name, this method removes the first field that has been added. @@ -116,7 +121,7 @@ */ public final BytesRef[] getBinaryValues(String name) { final List result = new ArrayList(); - for (IndexableField field : fields) { + for (StorableField field : storedFields) { if (field.name().equals(name)) { final BytesRef bytes = field.binaryValue(); if (bytes != null) { @@ -138,7 +143,7 @@ * @return a byte[] containing the binary field value or null */ public final BytesRef getBinaryValue(String name) { - for (IndexableField field : fields) { + for (StorableField field : storedFields) { if (field.name().equals(name)) { final BytesRef bytes = field.binaryValue(); if (bytes != null) { @@ -205,7 +210,7 @@ */ public final String[] getValues(String name) { List result = new ArrayList(); - for (IndexableField field : fields) { + for (StorableField field : storedFields) { if (field.name().equals(name) && field.stringValue() != null) { result.add(field.stringValue()); } @@ -227,7 +232,7 @@ * the actual numeric field instance back, use {@link #getField}. */ public final String get(String name) { - for (IndexableField field : fields) { + for (StorableField field : storedFields) { if (field.name().equals(name) && field.stringValue() != null) { return field.stringValue(); } @@ -249,4 +254,14 @@ buffer.append(">"); return buffer.toString(); } + + @Override + public Iterable indexableFields() { + return this.fields; + } + + @Override + public Iterable storableFields() { + return this.storedFields; + } } Index: lucene/core/src/java/org/apache/lucene/document/DocumentStoredFieldVisitor.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/DocumentStoredFieldVisitor.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/DocumentStoredFieldVisitor.java (working copy) @@ -34,7 +34,7 @@ * @lucene.experimental */ public class DocumentStoredFieldVisitor extends StoredFieldVisitor { - private final Document doc = new Document(); + private final StoredDocument doc = new StoredDocument(); private final Set fieldsToAdd; /** Load only fields named in the provided Set<String>. */ @@ -62,13 +62,16 @@ @Override public void stringField(FieldInfo fieldInfo, String value) throws IOException { + /* final FieldType ft = new FieldType(TextField.TYPE_STORED); ft.setStoreTermVectors(fieldInfo.storeTermVector); ft.setStoreTermVectors(fieldInfo.storeTermVector); ft.setIndexed(fieldInfo.isIndexed); ft.setOmitNorms(fieldInfo.omitNorms); ft.setIndexOptions(fieldInfo.indexOptions); - doc.add(new Field(fieldInfo.name, value, ft)); + */ + doc.add(new StoredField(fieldInfo.name, value)); + //doc.add(new Field(fieldInfo.name, value, ft)); } @Override @@ -96,7 +99,7 @@ return fieldsToAdd == null || fieldsToAdd.contains(fieldInfo.name) ? Status.YES : Status.NO; } - public Document getDocument() { + public StoredDocument getDocument() { return doc; } } Index: lucene/core/src/java/org/apache/lucene/document/DoubleDocValuesField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/DoubleDocValuesField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/DoubleDocValuesField.java (working copy) @@ -34,9 +34,9 @@ * separate {@link StoredField} instance. * */ -public class DoubleDocValuesField extends Field { +public class DoubleDocValuesField extends StoredField { - public static final FieldType TYPE = new FieldType(); + public static final StoredFieldType TYPE = new StoredFieldType(); static { TYPE.setDocValueType(DocValues.Type.FLOAT_64); TYPE.freeze(); Index: lucene/core/src/java/org/apache/lucene/document/DoubleField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/DoubleField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/DoubleField.java (working copy) @@ -120,7 +120,6 @@ public static final FieldType TYPE = new FieldType(); static { - TYPE.setIndexed(true); TYPE.setTokenized(true); TYPE.setOmitNorms(true); TYPE.setIndexOptions(IndexOptions.DOCS_ONLY); Index: lucene/core/src/java/org/apache/lucene/document/Field.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/Field.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/Field.java (working copy) @@ -31,6 +31,7 @@ import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.IndexableFieldType; import org.apache.lucene.index.Norm; // javadocs +import org.apache.lucene.index.StorableField; import org.apache.lucene.util.BytesRef; import org.apache.lucene.index.FieldInvertState; // javadocs @@ -101,10 +102,7 @@ if (reader == null) { throw new NullPointerException("reader cannot be null"); } - if (type.stored()) { - throw new IllegalArgumentException("fields with a Reader value cannot be stored"); - } - if (type.indexed() && !type.tokenized()) { + if (!type.tokenized()) { throw new IllegalArgumentException("non-tokenized fields must use String values"); } @@ -123,51 +121,16 @@ if (tokenStream == null) { throw new NullPointerException("tokenStream cannot be null"); } - if (!type.indexed() || !type.tokenized()) { + if (!type.tokenized()) { throw new IllegalArgumentException("TokenStream fields must be indexed and tokenized"); } - if (type.stored()) { - throw new IllegalArgumentException("TokenStream fields cannot be stored"); - } this.name = name; this.fieldsData = null; this.tokenStream = tokenStream; this.type = type; } - - /** - * Create field with binary value. - */ - public Field(String name, byte[] value, FieldType type) { - this(name, value, 0, value.length, type); - } - /** - * Create field with binary value. - */ - public Field(String name, byte[] value, int offset, int length, FieldType type) { - this(name, new BytesRef(value, offset, length), type); - } - - /** - * Create field with binary value. - * - *

    NOTE: the provided BytesRef is not copied so be sure - * not to change it until you're done with this field. - */ - public Field(String name, BytesRef bytes, FieldType type) { - if (name == null) { - throw new IllegalArgumentException("name cannot be null"); - } - if (type.indexed()) { - throw new IllegalArgumentException("Fields with BytesRef values cannot be indexed"); - } - this.fieldsData = bytes; - this.type = type; - this.name = name; - } - // TODO: allow direct construction of int, long, float, double value too..? /** @@ -180,14 +143,6 @@ if (value == null) { throw new IllegalArgumentException("value cannot be null"); } - if (!type.stored() && !type.indexed()) { - throw new IllegalArgumentException("it doesn't make sense to have a field that " - + "is neither indexed nor stored"); - } - if (!type.indexed() && (type.storeTermVectors())) { - throw new IllegalArgumentException("cannot store term vector information " - + "for a field that is not indexed"); - } this.type = type; this.name = name; @@ -253,32 +208,7 @@ } fieldsData = value; } - - /** - * Expert: change the value of this field. See - * {@link #setStringValue(String)}. - */ - public void setBytesValue(byte[] value) { - setBytesValue(new BytesRef(value)); - } - /** - * Expert: change the value of this field. See - * {@link #setStringValue(String)}. - * - *

    NOTE: the provided BytesRef is not copied so be sure - * not to change it until you're done with this field. - */ - public void setBytesValue(BytesRef value) { - if (!(fieldsData instanceof BytesRef)) { - throw new IllegalArgumentException("cannot change value type from " + fieldsData.getClass().getSimpleName() + " to BytesRef"); - } - if (type.indexed()) { - throw new IllegalArgumentException("cannot set a Reader value on an indexed field"); - } - fieldsData = value; - } - public void setByteValue(byte value) { if (!(fieldsData instanceof Byte)) { throw new IllegalArgumentException("cannot change value type from " + fieldsData.getClass().getSimpleName() + " to Byte"); @@ -345,8 +275,8 @@ * values from stringValue() or getBinaryValue() */ public void setTokenStream(TokenStream tokenStream) { - if (!type.indexed() || !type.tokenized()) { - throw new IllegalArgumentException("TokenStream fields must be indexed and tokenized"); + if (!type.tokenized()) { + throw new IllegalArgumentException("TokenStream fields tokenized"); } if (type.numericType() != null) { throw new IllegalArgumentException("cannot set private TokenStream on numeric fields"); @@ -422,10 +352,7 @@ * {@inheritDoc} */ public TokenStream tokenStream(Analyzer analyzer) throws IOException { - if (!fieldType().indexed()) { - return null; - } - + final NumericType numericType = fieldType().numericType(); if (numericType != null) { if (numericTokenStream == null) { @@ -752,23 +679,19 @@ public static final FieldType translateFieldType(Store store, Index index, TermVector termVector) { final FieldType ft = new FieldType(); - ft.setStored(store == Store.YES); + //ft.setStored(store == Store.YES); switch(index) { case ANALYZED: - ft.setIndexed(true); ft.setTokenized(true); break; case ANALYZED_NO_NORMS: - ft.setIndexed(true); ft.setTokenized(true); ft.setOmitNorms(true); break; case NOT_ANALYZED: - ft.setIndexed(true); break; case NOT_ANALYZED_NO_NORMS: - ft.setIndexed(true); ft.setOmitNorms(true); break; case NO: @@ -911,32 +834,4 @@ public Field(String name, TokenStream tokenStream, TermVector termVector) { this(name, tokenStream, translateFieldType(Store.NO, Index.ANALYZED, termVector)); } - - /** - * Create a stored field with binary value. Optionally the value may be compressed. - * - * @param name The name of the field - * @param value The binary value - * - * @deprecated Use {@link StoredField} instead. - */ - @Deprecated - public Field(String name, byte[] value) { - this(name, value, translateFieldType(Store.YES, Index.NO, TermVector.NO)); - } - - /** - * Create a stored field with binary value. Optionally the value may be compressed. - * - * @param name The name of the field - * @param value The binary value - * @param offset Starting offset in value where this Field's bytes are - * @param length Number of bytes to use for this Field, starting at offset - * - * @deprecated Use {@link StoredField} instead. - */ - @Deprecated - public Field(String name, byte[] value, int offset, int length) { - this(name, value, offset, length, translateFieldType(Store.YES, Index.NO, TermVector.NO)); - } } Index: lucene/core/src/java/org/apache/lucene/document/FieldType.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/FieldType.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/FieldType.java (working copy) @@ -33,29 +33,23 @@ */ public static enum NumericType {INT, LONG, FLOAT, DOUBLE} - private boolean indexed; - private boolean stored; private boolean tokenized; private boolean storeTermVectors; private boolean storeTermVectorOffsets; private boolean storeTermVectorPositions; private boolean omitNorms; private IndexOptions indexOptions = IndexOptions.DOCS_AND_FREQS_AND_POSITIONS; - private DocValues.Type docValueType; private NumericType numericType; private boolean frozen; private int numericPrecisionStep = NumericUtils.PRECISION_STEP_DEFAULT; public FieldType(FieldType ref) { - this.indexed = ref.indexed(); - this.stored = ref.stored(); this.tokenized = ref.tokenized(); this.storeTermVectors = ref.storeTermVectors(); this.storeTermVectorOffsets = ref.storeTermVectorOffsets(); this.storeTermVectorPositions = ref.storeTermVectorPositions(); this.omitNorms = ref.omitNorms(); this.indexOptions = ref.indexOptions(); - this.docValueType = ref.docValueType(); this.numericType = ref.numericType(); // Do not copy frozen! } @@ -77,25 +71,7 @@ public void freeze() { this.frozen = true; } - - public boolean indexed() { - return this.indexed; - } - - public void setIndexed(boolean value) { - checkIfFrozen(); - this.indexed = value; - } - public boolean stored() { - return this.stored; - } - - public void setStored(boolean value) { - checkIfFrozen(); - this.stored = value; - } - public boolean tokenized() { return this.tokenized; } @@ -150,16 +126,6 @@ this.indexOptions = value; } - public void setDocValueType(DocValues.Type type) { - checkIfFrozen(); - docValueType = type; - } - - @Override - public DocValues.Type docValueType() { - return docValueType; - } - public void setNumericType(NumericType type) { checkIfFrozen(); numericType = type; @@ -190,51 +156,42 @@ @Override public final String toString() { StringBuilder result = new StringBuilder(); - if (stored()) { - result.append("stored"); + if (result.length() > 0) + result.append(","); + result.append("indexed"); + if (tokenized()) { + if (result.length() > 0) + result.append(","); + result.append("tokenized"); } - if (indexed()) { + if (storeTermVectors()) { if (result.length() > 0) result.append(","); - result.append("indexed"); - if (tokenized()) { - if (result.length() > 0) - result.append(","); - result.append("tokenized"); - } - if (storeTermVectors()) { - if (result.length() > 0) - result.append(","); - result.append("termVector"); - } - if (storeTermVectorOffsets()) { - if (result.length() > 0) - result.append(","); - result.append("termVectorOffsets"); - } - if (storeTermVectorPositions()) { - if (result.length() > 0) - result.append(","); - result.append("termVectorPosition"); - } - if (omitNorms()) { - result.append(",omitNorms"); - } - if (indexOptions != IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) { - result.append(",indexOptions="); - result.append(indexOptions); - } - if (numericType != null) { - result.append(",numericType="); - result.append(numericType); - result.append(",numericPrecisionStep="); - result.append(numericPrecisionStep); - } + result.append("termVector"); } - if (docValueType != null) { - result.append(",docValueType="); - result.append(docValueType); + if (storeTermVectorOffsets()) { + if (result.length() > 0) + result.append(","); + result.append("termVectorOffsets"); } + if (storeTermVectorPositions()) { + if (result.length() > 0) + result.append(","); + result.append("termVectorPosition"); + } + if (omitNorms()) { + result.append(",omitNorms"); + } + if (indexOptions != IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) { + result.append(",indexOptions="); + result.append(indexOptions); + } + if (numericType != null) { + result.append(",numericType="); + result.append(numericType); + result.append(",numericPrecisionStep="); + result.append(numericPrecisionStep); + } return result.toString(); } Index: lucene/core/src/java/org/apache/lucene/document/FloatDocValuesField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/FloatDocValuesField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/FloatDocValuesField.java (working copy) @@ -34,9 +34,9 @@ * separate {@link StoredField} instance. * */ -public class FloatDocValuesField extends Field { +public class FloatDocValuesField extends StoredField { - public static final FieldType TYPE = new FieldType(); + public static final StoredFieldType TYPE = new StoredFieldType(); static { TYPE.setDocValueType(DocValues.Type.FLOAT_32); TYPE.freeze(); Index: lucene/core/src/java/org/apache/lucene/document/FloatField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/FloatField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/FloatField.java (working copy) @@ -120,7 +120,6 @@ public static final FieldType TYPE = new FieldType(); static { - TYPE.setIndexed(true); TYPE.setTokenized(true); TYPE.setOmitNorms(true); TYPE.setIndexOptions(IndexOptions.DOCS_ONLY); Index: lucene/core/src/java/org/apache/lucene/document/IntDocValuesField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/IntDocValuesField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/IntDocValuesField.java (working copy) @@ -34,9 +34,9 @@ * separate {@link StoredField} instance. * */ -public class IntDocValuesField extends Field { +public class IntDocValuesField extends StoredField { - public static final FieldType TYPE = new FieldType(); + public static final StoredFieldType TYPE = new StoredFieldType(); static { TYPE.setDocValueType(DocValues.Type.FIXED_INTS_32); TYPE.freeze(); Index: lucene/core/src/java/org/apache/lucene/document/IntField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/IntField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/IntField.java (working copy) @@ -120,7 +120,6 @@ public static final FieldType TYPE = new FieldType(); static { - TYPE.setIndexed(true); TYPE.setTokenized(true); TYPE.setOmitNorms(true); TYPE.setIndexOptions(IndexOptions.DOCS_ONLY); Index: lucene/core/src/java/org/apache/lucene/document/LongDocValuesField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/LongDocValuesField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/LongDocValuesField.java (working copy) @@ -34,9 +34,9 @@ * separate {@link StoredField} instance. * */ -public class LongDocValuesField extends Field { +public class LongDocValuesField extends StoredField { - public static final FieldType TYPE = new FieldType(); + public static final StoredFieldType TYPE = new StoredFieldType(); static { TYPE.setDocValueType(DocValues.Type.FIXED_INTS_64); TYPE.freeze(); Index: lucene/core/src/java/org/apache/lucene/document/LongField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/LongField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/LongField.java (working copy) @@ -130,7 +130,6 @@ public static final FieldType TYPE = new FieldType(); static { - TYPE.setIndexed(true); TYPE.setTokenized(true); TYPE.setOmitNorms(true); TYPE.setIndexOptions(IndexOptions.DOCS_ONLY); Index: lucene/core/src/java/org/apache/lucene/document/PackedLongDocValuesField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/PackedLongDocValuesField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/PackedLongDocValuesField.java (working copy) @@ -37,9 +37,9 @@ * separate {@link StoredField} instance. * */ -public class PackedLongDocValuesField extends Field { +public class PackedLongDocValuesField extends StoredField { - public static final FieldType TYPE = new FieldType(); + public static final StoredFieldType TYPE = new StoredFieldType(); static { TYPE.setDocValueType(DocValues.Type.VAR_INTS); TYPE.freeze(); Index: lucene/core/src/java/org/apache/lucene/document/ShortDocValuesField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/ShortDocValuesField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/ShortDocValuesField.java (working copy) @@ -34,9 +34,9 @@ * separate {@link StoredField} instance. * */ -public class ShortDocValuesField extends Field { +public class ShortDocValuesField extends StoredField { - public static final FieldType TYPE = new FieldType(); + public static final StoredFieldType TYPE = new StoredFieldType(); static { TYPE.setDocValueType(DocValues.Type.FIXED_INTS_16); TYPE.freeze(); Index: lucene/core/src/java/org/apache/lucene/document/SortedBytesDocValuesField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/SortedBytesDocValuesField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/SortedBytesDocValuesField.java (working copy) @@ -35,16 +35,16 @@ * separate {@link StoredField} instance. * */ -public class SortedBytesDocValuesField extends Field { +public class SortedBytesDocValuesField extends StoredField { // TODO: ideally indexer figures out var vs fixed on its own!? - public static final FieldType TYPE_FIXED_LEN = new FieldType(); + public static final StoredFieldType TYPE_FIXED_LEN = new StoredFieldType(); static { TYPE_FIXED_LEN.setDocValueType(DocValues.Type.BYTES_FIXED_SORTED); TYPE_FIXED_LEN.freeze(); } - public static final FieldType TYPE_VAR_LEN = new FieldType(); + public static final StoredFieldType TYPE_VAR_LEN = new StoredFieldType(); static { TYPE_VAR_LEN.setDocValueType(DocValues.Type.BYTES_VAR_SORTED); TYPE_VAR_LEN.freeze(); Index: lucene/core/src/java/org/apache/lucene/document/StoredDocument.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/StoredDocument.java (revision 0) +++ lucene/core/src/java/org/apache/lucene/document/StoredDocument.java (working copy) @@ -0,0 +1,192 @@ +package org.apache.lucene.document; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.StorableField; +import org.apache.lucene.index.StorableField; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.util.BytesRef; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class StoredDocument implements Iterable{ + + private final List fields = new ArrayList(); + + + public final void add(StorableField field) { + fields.add(field); + } + + public StorableField[] getFields(String name) { + List result = new ArrayList(); + for (StorableField field : fields) { + if (field.name().equals(name)) { + result.add(field); + } + } + + return result.toArray(new StorableField[result.size()]); + } + + public final StorableField getField(String name) { + for (StorableField field : fields) { + if (field.name().equals(name)) { + return field; + } + } + return null; + } + + public final void removeField(String name) { + Iterator it = fields.iterator(); + while (it.hasNext()) { + StorableField field = it.next(); + if (field.name().equals(name)) { + it.remove(); + return; + } + } + } + + /** + *

    Removes all fields with the given name from the document. + * If there is no field with the specified name, the document remains unchanged.

    + *

    Note that the removeField(s) methods like the add method only make sense + * prior to adding a document to an index. These methods cannot + * be used to change the content of an existing index! In order to achieve this, + * a document has to be deleted from an index and a new changed version of that + * document has to be added.

    + */ + public final void removeFields(String name) { + Iterator it = fields.iterator(); + while (it.hasNext()) { + StorableField field = it.next(); + if (field.name().equals(name)) { + it.remove(); + } + } + } + + public final List getFields() { + return fields; + } + + @Override + public Iterator iterator() { + return this.fields.iterator(); + } + + /** + * Returns an array of byte arrays for of the fields that have the name specified + * as the method parameter. This method returns an empty + * array when there are no matching fields. It never + * returns null. + * + * @param name the name of the field + * @return a byte[][] of binary field values + */ + public final BytesRef[] getBinaryValues(String name) { + final List result = new ArrayList(); + for (StorableField field : fields) { + if (field.name().equals(name)) { + final BytesRef bytes = field.binaryValue(); + if (bytes != null) { + result.add(bytes); + } + } + } + + return result.toArray(new BytesRef[result.size()]); + } + + /** + * Returns an array of bytes for the first (or only) field that has the name + * specified as the method parameter. This method will return null + * if no binary fields with the specified name are available. + * There may be non-binary fields with the same name. + * + * @param name the name of the field. + * @return a byte[] containing the binary field value or null + */ + public final BytesRef getBinaryValue(String name) { + for (StorableField field : fields) { + if (field.name().equals(name)) { + final BytesRef bytes = field.binaryValue(); + if (bytes != null) { + return bytes; + } + } + } + return null; + } + private final static String[] NO_STRINGS = new String[0]; + + /** + * Returns an array of values of the field specified as the method parameter. + * This method returns an empty array when there are no + * matching fields. It never returns null. + * For {@link IntField}, {@link LongField}, {@link + * FloatField} and {@link DoubleField} it returns the string value of the number. If you want + * the actual numeric field instances back, use {@link #getFields}. + * @param name the name of the field + * @return a String[] of field values + */ + public final String[] getValues(String name) { + List result = new ArrayList(); + for (StorableField field : fields) { + if (field.name().equals(name) && field.stringValue() != null) { + result.add(field.stringValue()); + } + } + + if (result.size() == 0) { + return NO_STRINGS; + } + + return result.toArray(new String[result.size()]); + } + + /** Returns the string value of the field with the given name if any exist in + * this document, or null. If multiple fields exist with this name, this + * method returns the first value added. If only binary fields with this name + * exist, returns null. + * For {@link IntField}, {@link LongField}, {@link + * FloatField} and {@link DoubleField} it returns the string value of the number. If you want + * the actual numeric field instance back, use {@link #getField}. + */ + public final String get(String name) { + for (StorableField field : fields) { + if (field.name().equals(name) && field.stringValue() != null) { + return field.stringValue(); + } + } + return null; + } + + public Document asIndexable() { + Document doc = new Document(); + /* TODO */ + + return doc; + } +} Index: lucene/core/src/java/org/apache/lucene/document/StoredField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/StoredField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/StoredField.java (working copy) @@ -1,6 +1,10 @@ package org.apache.lucene.document; +import java.io.Reader; + import org.apache.lucene.index.IndexReader; // javadocs +import org.apache.lucene.index.StorableField; +import org.apache.lucene.index.StorableFieldType; import org.apache.lucene.search.IndexSearcher; // javadocs import org.apache.lucene.util.BytesRef; @@ -24,48 +28,186 @@ /** A field whose value is stored so that {@link * IndexSearcher#doc} and {@link IndexReader#document} will * return the field and its value. */ -public final class StoredField extends Field { +public class StoredField implements StorableField { - public final static FieldType TYPE; + public final static StoredFieldType TYPE; + static { - TYPE = new FieldType(); - TYPE.setStored(true); + TYPE = new StoredFieldType(); TYPE.freeze(); } + protected Object fieldsData; + protected final String name; + protected final StoredFieldType type; + + protected StoredField(String name, StoredFieldType type) { + this.name = name; + this.type = type; + } + + public StoredField(String name, BytesRef bytes, StoredFieldType type) { + if (name == null) { + throw new IllegalArgumentException("name cannot be null"); + } + this.fieldsData = bytes; + this.name = name; + this.type = type; + } + public StoredField(String name, byte[] value) { - super(name, value, TYPE); + this(name, value, 0, value.length); } public StoredField(String name, byte[] value, int offset, int length) { - super(name, value, offset, length, TYPE); + this(name, new BytesRef(value, offset, length), TYPE); } - public StoredField(String name, BytesRef value) { - super(name, value, TYPE); - } - public StoredField(String name, String value) { - super(name, value, TYPE); + this(name, TYPE); + fieldsData = value; } public StoredField(String name, int value) { - super(name, TYPE); + this(name, TYPE); fieldsData = value; } public StoredField(String name, float value) { - super(name, TYPE); + this(name, TYPE); fieldsData = value; } public StoredField(String name, long value) { - super(name, TYPE); + this(name, TYPE); fieldsData = value; } public StoredField(String name, double value) { - super(name, TYPE); + this(name, TYPE); fieldsData = value; } + + @Override + public String name() { + return name; + } + + @Override + public StorableFieldType fieldType() { + return this.type; + } + + @Override + public BytesRef binaryValue() { + if (fieldsData instanceof BytesRef) { + return (BytesRef) fieldsData; + } else { + return null; + } + } + + /** + * The value of the field as a String, or null. If null, the Reader value or + * binary value is used. Exactly one of stringValue(), readerValue(), and + * getBinaryValue() must be set. + */ + @Override + public String stringValue() { + return fieldsData instanceof String ? (String) fieldsData : null; + } + + /** + * The value of the field as a Reader, or null. If null, the String value or + * binary value is used. Exactly one of stringValue(), readerValue(), and + * getBinaryValue() must be set. + */ + @Override + public Reader readerValue() { + return fieldsData instanceof Reader ? (Reader) fieldsData : null; + } + + @Override + public Number numericValue() { + if (fieldsData instanceof Number) { + return (Number) fieldsData; + } else { + return null; + } + } + + /** + * Expert: change the value of this field. See + * {@link #setStringValue(String)}. + */ + public void setBytesValue(byte[] value) { + setBytesValue(new BytesRef(value)); + } + + /** + * Expert: change the value of this field. See + * {@link #setStringValue(String)}. + * + *

    NOTE: the provided BytesRef is not copied so be sure + * not to change it until you're done with this field. + */ + public void setBytesValue(BytesRef value) { + if (!(fieldsData instanceof BytesRef)) { + throw new IllegalArgumentException("cannot change value type from " + fieldsData.getClass().getSimpleName() + " to BytesRef"); + } + fieldsData = value; + } + + /** + * Expert: change the value of this field. See + * {@link #setStringValue(String)}. + */ + public void setReaderValue(Reader value) { + if (!(fieldsData instanceof Reader)) { + throw new IllegalArgumentException("cannot change value type from " + fieldsData.getClass().getSimpleName() + " to Reader"); + } + fieldsData = value; + } + + public void setByteValue(byte value) { + if (!(fieldsData instanceof Byte)) { + throw new IllegalArgumentException("cannot change value type from " + fieldsData.getClass().getSimpleName() + " to Byte"); + } + fieldsData = Byte.valueOf(value); + } + + public void setShortValue(short value) { + if (!(fieldsData instanceof Short)) { + throw new IllegalArgumentException("cannot change value type from " + fieldsData.getClass().getSimpleName() + " to Short"); + } + fieldsData = Short.valueOf(value); + } + + public void setIntValue(int value) { + if (!(fieldsData instanceof Integer)) { + throw new IllegalArgumentException("cannot change value type from " + fieldsData.getClass().getSimpleName() + " to Integer"); + } + fieldsData = Integer.valueOf(value); + } + + public void setLongValue(long value) { + if (!(fieldsData instanceof Long)) { + throw new IllegalArgumentException("cannot change value type from " + fieldsData.getClass().getSimpleName() + " to Long"); + } + fieldsData = Long.valueOf(value); + } + + public void setFloatValue(float value) { + if (!(fieldsData instanceof Float)) { + throw new IllegalArgumentException("cannot change value type from " + fieldsData.getClass().getSimpleName() + " to Float"); + } + fieldsData = Float.valueOf(value); + } + + public void setDoubleValue(double value) { + if (!(fieldsData instanceof Double)) { + throw new IllegalArgumentException("cannot change value type from " + fieldsData.getClass().getSimpleName() + " to Double"); + } + fieldsData = Double.valueOf(value); + } } Index: lucene/core/src/java/org/apache/lucene/document/StoredFieldType.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/StoredFieldType.java (revision 0) +++ lucene/core/src/java/org/apache/lucene/document/StoredFieldType.java (working copy) @@ -0,0 +1,112 @@ +package org.apache.lucene.document; + +import org.apache.lucene.index.DocValues; +import org.apache.lucene.index.StorableFieldType; +import org.apache.lucene.search.NumericRangeQuery; +import org.apache.lucene.util.NumericUtils; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class StoredFieldType implements StorableFieldType { + + /** Data type of the numeric value + * @since 3.2 + */ + public static enum NumericType {INT, LONG, FLOAT, DOUBLE} + + private boolean frozen; + private DocValues.Type docValueType; + private NumericType numericType; + private int numericPrecisionStep = NumericUtils.PRECISION_STEP_DEFAULT; + + public StoredFieldType() { + } + + public StoredFieldType(StoredFieldType ref) { + this.docValueType = ref.docValueType(); + this.numericType = ref.numericType(); + // Do not copy frozen! + } + + public void freeze() { + this.frozen = true; + } + + private void checkIfFrozen() { + if (frozen) { + throw new IllegalStateException("this FieldType is already frozen and cannot be changed"); + } + } + + @Override + public DocValues.Type docValueType() { + return docValueType; + } + + public void setDocValueType(DocValues.Type type) { + checkIfFrozen(); + docValueType = type; + } + + public void setNumericType(NumericType type) { + checkIfFrozen(); + numericType = type; + } + + /** NumericDataType; if + * non-null then the field's value will be indexed + * numerically so that {@link NumericRangeQuery} can be + * used at search time. */ + public NumericType numericType() { + return numericType; + } + + /** Precision step for numeric field. */ + public int numericPrecisionStep() { + return numericPrecisionStep; + } + + public void setNumericPrecisionStep(int precisionStep) { + checkIfFrozen(); + if (precisionStep < 1) { + throw new IllegalArgumentException("precisionStep must be >= 1 (got " + precisionStep + ")"); + } + this.numericPrecisionStep = precisionStep; + } + + /** Prints a Field for human consumption. */ + @Override + public final String toString() { + StringBuilder result = new StringBuilder(); + if (result.length() > 0) + result.append(","); + result.append("stored"); + if (numericType != null) { + result.append(",numericType="); + result.append(numericType); + result.append(",numericPrecisionStep="); + result.append(numericPrecisionStep); + } + if (docValueType != null) { + result.append(",docValueType="); + result.append(docValueType); + } + + return result.toString(); + } +} Index: lucene/core/src/java/org/apache/lucene/document/StraightBytesDocValuesField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/StraightBytesDocValuesField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/StraightBytesDocValuesField.java (working copy) @@ -38,16 +38,16 @@ * separate {@link StoredField} instance. * */ -public class StraightBytesDocValuesField extends Field { +public class StraightBytesDocValuesField extends StoredField { // TODO: ideally indexer figures out var vs fixed on its own!? - public static final FieldType TYPE_FIXED_LEN = new FieldType(); + public static final StoredFieldType TYPE_FIXED_LEN = new StoredFieldType(); static { TYPE_FIXED_LEN.setDocValueType(DocValues.Type.BYTES_FIXED_STRAIGHT); TYPE_FIXED_LEN.freeze(); } - public static final FieldType TYPE_VAR_LEN = new FieldType(); + public static final StoredFieldType TYPE_VAR_LEN = new StoredFieldType(); static { TYPE_VAR_LEN.setDocValueType(DocValues.Type.BYTES_VAR_STRAIGHT); TYPE_VAR_LEN.freeze(); Index: lucene/core/src/java/org/apache/lucene/document/StringField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/StringField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/StringField.java (working copy) @@ -35,21 +35,10 @@ * DOCS_ONLY, not stored. */ public static final FieldType TYPE_UNSTORED = new FieldType(); - /** Indexed, not tokenized, omits norms, indexes - * DOCS_ONLY, stored */ - public static final FieldType TYPE_STORED = new FieldType(); - static { - TYPE_UNSTORED.setIndexed(true); TYPE_UNSTORED.setOmitNorms(true); TYPE_UNSTORED.setIndexOptions(IndexOptions.DOCS_ONLY); TYPE_UNSTORED.freeze(); - - TYPE_STORED.setIndexed(true); - TYPE_STORED.setStored(true); - TYPE_STORED.setOmitNorms(true); - TYPE_STORED.setIndexOptions(IndexOptions.DOCS_ONLY); - TYPE_STORED.freeze(); } /** Creates a new un-stored StringField */ Index: lucene/core/src/java/org/apache/lucene/document/TextField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/document/TextField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/document/TextField.java (working copy) @@ -33,19 +33,10 @@ /* Indexed, tokenized, not stored. */ public static final FieldType TYPE_UNSTORED = new FieldType(); - - /* Indexed, tokenized, stored. */ - public static final FieldType TYPE_STORED = new FieldType(); - + static { - TYPE_UNSTORED.setIndexed(true); TYPE_UNSTORED.setTokenized(true); TYPE_UNSTORED.freeze(); - - TYPE_STORED.setIndexed(true); - TYPE_STORED.setStored(true); - TYPE_STORED.setTokenized(true); - TYPE_STORED.freeze(); } // TODO: add sugar for term vectors...? Index: lucene/core/src/java/org/apache/lucene/index/CheckIndex.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/CheckIndex.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/index/CheckIndex.java (working copy) @@ -31,6 +31,7 @@ import org.apache.lucene.codecs.Codec; import org.apache.lucene.document.Document; import org.apache.lucene.document.FieldType; // for javadocs +import org.apache.lucene.document.StoredDocument; import org.apache.lucene.index.DocValues.SortedSource; import org.apache.lucene.index.DocValues.Source; import org.apache.lucene.search.DocIdSetIterator; @@ -1199,7 +1200,7 @@ for (int j = 0; j < info.docCount; ++j) { // Intentionally pull even deleted documents to // make sure they too are not corrupt: - Document doc = reader.document(j); + StoredDocument doc = reader.document(j); if (liveDocs == null || liveDocs.get(j)) { status.docCount++; status.totFields += doc.getFields().size(); Index: lucene/core/src/java/org/apache/lucene/index/DocFieldProcessor.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/DocFieldProcessor.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/index/DocFieldProcessor.java (working copy) @@ -217,7 +217,7 @@ // seen before (eg suddenly turning on norms or // vectors, etc.): - for(IndexableField field : docState.doc) { + for(IndexableField field : docState.doc.indexableFields()) { final String fieldName = field.name(); // Make sure we have a PerField allocated @@ -265,13 +265,20 @@ } fp.addField(field); + } + for (StorableField field: docState.doc.storableFields()) { + final String fieldName = field.name(); - if (field.fieldType().stored()) { - fieldsWriter.addField(field, fp.fieldInfo); + // Make sure we have a PerField allocated + final int hashPos = fieldName.hashCode() & hashMask; + DocFieldProcessorPerField fp = fieldHash[hashPos]; + while(fp != null && !fp.fieldInfo.name.equals(fieldName)) { + fp = fp.next; } + final DocValues.Type dvType = field.fieldType().docValueType(); if (dvType != null) { - docValuesConsumer(dvType, docState, fp.fieldInfo).add(docState.docID, field); + docValuesConsumer(dvType, docState, fp.fieldInfo).add(docState.docID, (StorableField) field); } } Index: lucene/core/src/java/org/apache/lucene/index/DocInverterPerField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/DocInverterPerField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/index/DocInverterPerField.java (working copy) @@ -72,7 +72,7 @@ // TODO FI: this should be "genericized" to querying // consumer if it wants to see this particular field // tokenized. - if (fieldType.indexed() && doInvert) { + if (doInvert) { // if the field omits norms, the boost cannot be indexed. if (fieldType.omitNorms() && field.boost() != 1.0f) { Index: lucene/core/src/java/org/apache/lucene/index/Document.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/Document.java (revision 0) +++ lucene/core/src/java/org/apache/lucene/index/Document.java (working copy) @@ -0,0 +1,23 @@ +package org.apache.lucene.index; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public interface Document { + public Iterable indexableFields(); + public Iterable storableFields(); +} Index: lucene/core/src/java/org/apache/lucene/index/DocumentsWriter.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/DocumentsWriter.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/index/DocumentsWriter.java (working copy) @@ -324,7 +324,7 @@ return maybeMerge; } - boolean updateDocuments(final Iterable> docs, final Analyzer analyzer, + boolean updateDocuments(final Iterable docs, final Analyzer analyzer, final Term delTerm) throws CorruptIndexException, IOException { boolean maybeMerge = preUpdate(); @@ -355,7 +355,7 @@ return postUpdate(flushingDWPT, maybeMerge); } - boolean updateDocument(final Iterable doc, final Analyzer analyzer, + boolean updateDocument(final Document doc, final Analyzer analyzer, final Term delTerm) throws CorruptIndexException, IOException { boolean maybeMerge = preUpdate(); Index: lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java (working copy) @@ -90,7 +90,7 @@ InfoStream infoStream; Similarity similarity; int docID; - Iterable doc; + Document doc; String maxTermPrefix; DocState(DocumentsWriterPerThread docWriter, InfoStream infoStream) { @@ -217,7 +217,7 @@ return retval; } - public void updateDocument(Iterable doc, Analyzer analyzer, Term delTerm) throws IOException { + public void updateDocument(Document doc, Analyzer analyzer, Term delTerm) throws IOException { assert writer.testPoint("DocumentsWriterPerThread addDocument start"); assert deleteQueue != null; docState.doc = doc; @@ -266,7 +266,7 @@ finishDocument(delTerm); } - public int updateDocuments(Iterable> docs, Analyzer analyzer, Term delTerm) throws IOException { + public int updateDocuments(Iterable docs, Analyzer analyzer, Term delTerm) throws IOException { assert writer.testPoint("DocumentsWriterPerThread addDocuments start"); assert deleteQueue != null; docState.analyzer = analyzer; @@ -283,7 +283,7 @@ } int docCount = 0; try { - for(Iterable doc : docs) { + for(Document doc : docs) { docState.doc = doc; docState.docID = numDocsInRAM; docCount++; Index: lucene/core/src/java/org/apache/lucene/index/FieldInfos.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/FieldInfos.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/index/FieldInfos.java (working copy) @@ -296,7 +296,7 @@ // rather, each component in the chain should update // what it "owns". EG fieldType.indexOptions() should // be updated by maybe FreqProxTermsWriterPerField: - return addOrUpdateInternal(name, -1, fieldType.indexed(), false, + return addOrUpdateInternal(name, -1, true, false, fieldType.omitNorms(), false, fieldType.indexOptions(), null, null); } Index: lucene/core/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java (working copy) @@ -96,12 +96,7 @@ @Override boolean start(IndexableField[] fields, int count) { - for(int i=0;iThere are two different types of IndexReaders: -

      -
    • {@link AtomicReader}: These indexes do not consist of several sub-readers, - they are atomic. They support retrieval of stored fields, doc values, terms, - and postings. -
    • {@link CompositeReader}: Instances (like {@link DirectoryReader}) - of this reader can only - be used to get stored fields from the underlying AtomicReaders, - but it is not possible to directly retrieve postings. To do that, get - the sub-readers via {@link CompositeReader#getSequentialSubReaders}. - Alternatively, you can mimic an {@link AtomicReader} (with a serious slowdown), - by wrapping composite readers with {@link SlowCompositeReaderWrapper}. -
    - -

    IndexReader instances for indexes on disk are usually constructed - with a call to one of the static DirectoryReader,open() methods, - e.g. {@link DirectoryReader#open(Directory)}. {@link DirectoryReader} implements - the {@link CompositeReader} interface, it is not possible to directly get postings. - -

    For efficiency, in this API documents are often referred to via - document numbers, non-negative integers which each name a unique - document in the index. These document numbers are ephemeral -- they may change - as documents are added to and deleted from an index. Clients should thus not - rely on a given document having the same number between sessions. - -

    -

    NOTE: {@link - IndexReader} instances are completely thread - safe, meaning multiple threads can call any of its methods, - concurrently. If your application requires external - synchronization, you should not synchronize on the - IndexReader instance; use your own - (non-Lucene) objects instead. -*/ +/** + * IndexReader is an abstract class, providing an interface for accessing an + * index. Search of an index is done entirely through this abstract interface, + * so that any subclass which implements it is searchable. + * + *

    + * There are two different types of IndexReaders: + *

      + *
    • {@link AtomicReader}: These indexes do not consist of several + * sub-readers, they are atomic. They support retrieval of stored fields, doc + * values, terms, and postings. + *
    • {@link CompositeReader}: Instances (like {@link DirectoryReader}) of this + * reader can only be used to get stored fields from the underlying + * AtomicReaders, but it is not possible to directly retrieve postings. To do + * that, get the sub-readers via {@link CompositeReader#getSequentialSubReaders} + * . Alternatively, you can mimic an {@link AtomicReader} (with a serious + * slowdown), by wrapping composite readers with + * {@link SlowCompositeReaderWrapper}. + *
    + * + *

    + * IndexReader instances for indexes on disk are usually constructed with a call + * to one of the static DirectoryReader,open() methods, e.g. + * {@link DirectoryReader#open(Directory)}. {@link DirectoryReader} implements + * the {@link CompositeReader} interface, it is not possible to directly get + * postings. + * + *

    + * For efficiency, in this API documents are often referred to via document + * numbers, non-negative integers which each name a unique document in the + * index. These document numbers are ephemeral -- they may change as documents + * are added to and deleted from an index. Clients should thus not rely on a + * given document having the same number between sessions. + * + *

    + * + *

    + * NOTE: {@link IndexReader} instances are completely thread safe, + * meaning multiple threads can call any of its methods, concurrently. If your + * application requires external synchronization, you should not + * synchronize on the IndexReader instance; use your own + * (non-Lucene) objects instead. + */ public abstract class IndexReader implements Closeable { private boolean closed = false; private boolean closedByChild = false; private final AtomicInteger refCount = new AtomicInteger(1); - + IndexReader() { - if (!(this instanceof CompositeReader || this instanceof AtomicReader)) - throw new Error("IndexReader should never be directly extended, subclass AtomicReader or CompositeReader instead."); + if (!(this instanceof CompositeReader || this instanceof AtomicReader)) throw new Error( + "IndexReader should never be directly extended, subclass AtomicReader or CompositeReader instead."); } /** - * A custom listener that's invoked when the IndexReader - * is closed. - * + * A custom listener that's invoked when the IndexReader is closed. + * * @lucene.experimental */ public static interface ReaderClosedListener { public void onClose(IndexReader reader); } - - private final Set readerClosedListeners = - Collections.synchronizedSet(new LinkedHashSet()); - - private final Set parentReaders = - Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap())); - - /** Expert: adds a {@link ReaderClosedListener}. The - * provided listener will be invoked when this reader is closed. - * - * @lucene.experimental */ + + private final Set readerClosedListeners = Collections + .synchronizedSet(new LinkedHashSet()); + + private final Set parentReaders = Collections + .synchronizedSet(Collections + .newSetFromMap(new WeakHashMap())); + + /** + * Expert: adds a {@link ReaderClosedListener}. The provided listener will be + * invoked when this reader is closed. + * + * @lucene.experimental + */ public final void addReaderClosedListener(ReaderClosedListener listener) { ensureOpen(); readerClosedListeners.add(listener); } - - /** Expert: remove a previously added {@link ReaderClosedListener}. - * - * @lucene.experimental */ + + /** + * Expert: remove a previously added {@link ReaderClosedListener}. + * + * @lucene.experimental + */ public final void removeReaderClosedListener(ReaderClosedListener listener) { ensureOpen(); readerClosedListeners.remove(listener); } - /** Expert: This method is called by {@code IndexReader}s which wrap other readers - * (e.g. {@link CompositeReader} or {@link FilterAtomicReader}) to register the parent - * at the child (this reader) on construction of the parent. When this reader is closed, - * it will mark all registered parents as closed, too. The references to parent readers - * are weak only, so they can be GCed once they are no longer in use. - * @lucene.experimental */ + /** + * Expert: This method is called by {@code IndexReader}s which wrap other + * readers (e.g. {@link CompositeReader} or {@link FilterAtomicReader}) to + * register the parent at the child (this reader) on construction of the + * parent. When this reader is closed, it will mark all registered parents as + * closed, too. The references to parent readers are weak only, so they can be + * GCed once they are no longer in use. + * + * @lucene.experimental + */ public final void registerParentReader(IndexReader reader) { ensureOpen(); parentReaders.add(reader); } - + private void notifyReaderClosedListeners() { - synchronized(readerClosedListeners) { - for(ReaderClosedListener listener : readerClosedListeners) { + synchronized (readerClosedListeners) { + for (ReaderClosedListener listener : readerClosedListeners) { listener.onClose(this); } } } - + private void reportCloseToParentReaders() { - synchronized(parentReaders) { - for(IndexReader parent : parentReaders) { + synchronized (parentReaders) { + for (IndexReader parent : parentReaders) { parent.closedByChild = true; // cross memory barrier by a fake write: parent.refCount.addAndGet(0); @@ -145,7 +159,7 @@ } } } - + /** Expert: returns the current refCount for this reader */ public final int getRefCount() { // NOTE: don't ensureOpen, so that callers can see @@ -154,17 +168,14 @@ } /** - * Expert: increments the refCount of this IndexReader - * instance. RefCounts are used to determine when a - * reader can be closed safely, i.e. as soon as there are - * no more references. Be sure to always call a - * corresponding {@link #decRef}, in a finally clause; - * otherwise the reader may never be closed. Note that - * {@link #close} simply calls decRef(), which means that - * the IndexReader will not really be closed until {@link - * #decRef} has been called for all outstanding - * references. - * + * Expert: increments the refCount of this IndexReader instance. RefCounts are + * used to determine when a reader can be closed safely, i.e. as soon as there + * are no more references. Be sure to always call a corresponding + * {@link #decRef}, in a finally clause; otherwise the reader may never be + * closed. Note that {@link #close} simply calls decRef(), which means that + * the IndexReader will not really be closed until {@link #decRef} has been + * called for all outstanding references. + * * @see #decRef * @see #tryIncRef */ @@ -174,46 +185,41 @@ } /** - * Expert: increments the refCount of this IndexReader - * instance only if the IndexReader has not been closed yet - * and returns true iff the refCount was - * successfully incremented, otherwise false. - * If this method returns false the reader is either - * already closed or is currently been closed. Either way this - * reader instance shouldn't be used by an application unless - * true is returned. + * Expert: increments the refCount of this IndexReader instance only if the + * IndexReader has not been closed yet and returns true iff the + * refCount was successfully incremented, otherwise false. If + * this method returns false the reader is either already closed + * or is currently been closed. Either way this reader instance shouldn't be + * used by an application unless true is returned. *

    - * RefCounts are used to determine when a - * reader can be closed safely, i.e. as soon as there are - * no more references. Be sure to always call a - * corresponding {@link #decRef}, in a finally clause; - * otherwise the reader may never be closed. Note that - * {@link #close} simply calls decRef(), which means that - * the IndexReader will not really be closed until {@link - * #decRef} has been called for all outstanding - * references. - * + * RefCounts are used to determine when a reader can be closed safely, i.e. as + * soon as there are no more references. Be sure to always call a + * corresponding {@link #decRef}, in a finally clause; otherwise the reader + * may never be closed. Note that {@link #close} simply calls decRef(), which + * means that the IndexReader will not really be closed until {@link #decRef} + * has been called for all outstanding references. + * * @see #decRef * @see #incRef */ public final boolean tryIncRef() { int count; while ((count = refCount.get()) > 0) { - if (refCount.compareAndSet(count, count+1)) { + if (refCount.compareAndSet(count, count + 1)) { return true; } } return false; } - + /** - * Expert: decreases the refCount of this IndexReader - * instance. If the refCount drops to 0, then this - * reader is closed. If an exception is hit, the refCount - * is unchanged. - * - * @throws IOException in case an IOException occurs in doClose() - * + * Expert: decreases the refCount of this IndexReader instance. If the + * refCount drops to 0, then this reader is closed. If an exception is hit, + * the refCount is unchanged. + * + * @throws IOException + * in case an IOException occurs in doClose() + * * @see #incRef */ public final void decRef() throws IOException { @@ -238,28 +244,34 @@ reportCloseToParentReaders(); notifyReaderClosedListeners(); } else if (rc < 0) { - throw new IllegalStateException("too many decRef calls: refCount is " + rc + " after decrement"); + throw new IllegalStateException("too many decRef calls: refCount is " + + rc + " after decrement"); } } /** - * @throws AlreadyClosedException if this IndexReader is closed + * @throws AlreadyClosedException + * if this IndexReader is closed */ protected final void ensureOpen() throws AlreadyClosedException { if (refCount.get() <= 0) { throw new AlreadyClosedException("this IndexReader is closed"); } - // the happens before rule on reading the refCount, which must be after the fake write, + // the happens before rule on reading the refCount, which must be after the + // fake write, // ensures that we see the value: if (closedByChild) { - throw new AlreadyClosedException("this IndexReader cannot be used anymore as one of its child readers was closed"); + throw new AlreadyClosedException( + "this IndexReader cannot be used anymore as one of its child readers was closed"); } } - /** {@inheritDoc} - *

    For caching purposes, {@code IndexReader} subclasses are not allowed - * to implement equals/hashCode, so methods are declared final. - * To lookup instances from caches use {@link #getCoreCacheKey} and + /** + * {@inheritDoc} + *

    + * For caching purposes, {@code IndexReader} subclasses are not allowed to + * implement equals/hashCode, so methods are declared final. To lookup + * instances from caches use {@link #getCoreCacheKey} and * {@link #getCombinedCoreAndDeletesKey}. */ @Override @@ -267,10 +279,12 @@ return (this == obj); } - /** {@inheritDoc} - *

    For caching purposes, {@code IndexReader} subclasses are not allowed - * to implement equals/hashCode, so methods are declared final. - * To lookup instances from caches use {@link #getCoreCacheKey} and + /** + * {@inheritDoc} + *

    + * For caching purposes, {@code IndexReader} subclasses are not allowed to + * implement equals/hashCode, so methods are declared final. To lookup + * instances from caches use {@link #getCoreCacheKey} and * {@link #getCombinedCoreAndDeletesKey}. */ @Override @@ -278,188 +292,222 @@ return System.identityHashCode(this); } - /** Returns a IndexReader reading the index in the given - * Directory - * @param directory the index directory - * @throws CorruptIndexException if the index is corrupt - * @throws IOException if there is a low-level IO error + /** + * Returns a IndexReader reading the index in the given Directory + * + * @param directory + * the index directory + * @throws CorruptIndexException + * if the index is corrupt + * @throws IOException + * if there is a low-level IO error * @deprecated Use {@link DirectoryReader#open(Directory)} */ @Deprecated - public static DirectoryReader open(final Directory directory) throws CorruptIndexException, IOException { + public static DirectoryReader open(final Directory directory) + throws CorruptIndexException, IOException { return DirectoryReader.open(directory); } - /** Expert: Returns a IndexReader reading the index in the given - * Directory with the given termInfosIndexDivisor. - * @param directory the index directory - * @param termInfosIndexDivisor Subsamples which indexed - * terms are loaded into RAM. This has the same effect as {@link - * IndexWriterConfig#setTermIndexInterval} except that setting - * must be done at indexing time while this setting can be - * set per reader. When set to N, then one in every - * N*termIndexInterval terms in the index is loaded into - * memory. By setting this to a value > 1 you can reduce - * memory usage, at the expense of higher latency when - * loading a TermInfo. The default value is 1. Set this - * to -1 to skip loading the terms index entirely. - * @throws CorruptIndexException if the index is corrupt - * @throws IOException if there is a low-level IO error + /** + * Expert: Returns a IndexReader reading the index in the given Directory with + * the given termInfosIndexDivisor. + * + * @param directory + * the index directory + * @param termInfosIndexDivisor + * Subsamples which indexed terms are loaded into RAM. This has the + * same effect as {@link IndexWriterConfig#setTermIndexInterval} + * except that setting must be done at indexing time while this + * setting can be set per reader. When set to N, then one in every + * N*termIndexInterval terms in the index is loaded into memory. By + * setting this to a value > 1 you can reduce memory usage, at the + * expense of higher latency when loading a TermInfo. The default + * value is 1. Set this to -1 to skip loading the terms index + * entirely. + * @throws CorruptIndexException + * if the index is corrupt + * @throws IOException + * if there is a low-level IO error * @deprecated Use {@link DirectoryReader#open(Directory,int)} */ @Deprecated - public static DirectoryReader open(final Directory directory, int termInfosIndexDivisor) throws CorruptIndexException, IOException { + public static DirectoryReader open(final Directory directory, + int termInfosIndexDivisor) throws CorruptIndexException, IOException { return DirectoryReader.open(directory, termInfosIndexDivisor); } /** - * Open a near real time IndexReader from the {@link org.apache.lucene.index.IndexWriter}. - * - * @param writer The IndexWriter to open from - * @param applyAllDeletes If true, all buffered deletes will - * be applied (made visible) in the returned reader. If - * false, the deletes are not applied but remain buffered - * (in IndexWriter) so that they will be applied in the - * future. Applying deletes can be costly, so if your app - * can tolerate deleted documents being returned you might - * gain some performance by passing false. + * Open a near real time IndexReader from the + * {@link org.apache.lucene.index.IndexWriter}. + * + * @param writer + * The IndexWriter to open from + * @param applyAllDeletes + * If true, all buffered deletes will be applied (made visible) in + * the returned reader. If false, the deletes are not applied but + * remain buffered (in IndexWriter) so that they will be applied in + * the future. Applying deletes can be costly, so if your app can + * tolerate deleted documents being returned you might gain some + * performance by passing false. * @return The new IndexReader * @throws CorruptIndexException - * @throws IOException if there is a low-level IO error - * + * @throws IOException + * if there is a low-level IO error + * * @see DirectoryReader#openIfChanged(DirectoryReader,IndexWriter,boolean) - * + * * @lucene.experimental * @deprecated Use {@link DirectoryReader#open(IndexWriter,boolean)} */ @Deprecated - public static DirectoryReader open(final IndexWriter writer, boolean applyAllDeletes) throws CorruptIndexException, IOException { + public static DirectoryReader open(final IndexWriter writer, + boolean applyAllDeletes) throws CorruptIndexException, IOException { return DirectoryReader.open(writer, applyAllDeletes); } - - /** Expert: returns an IndexReader reading the index in the given - * {@link IndexCommit}. - * @param commit the commit point to open - * @throws CorruptIndexException if the index is corrupt - * @throws IOException if there is a low-level IO error + + /** + * Expert: returns an IndexReader reading the index in the given + * {@link IndexCommit}. + * + * @param commit + * the commit point to open + * @throws CorruptIndexException + * if the index is corrupt + * @throws IOException + * if there is a low-level IO error * @deprecated Use {@link DirectoryReader#open(IndexCommit)} */ @Deprecated - public static DirectoryReader open(final IndexCommit commit) throws CorruptIndexException, IOException { + public static DirectoryReader open(final IndexCommit commit) + throws CorruptIndexException, IOException { return DirectoryReader.open(commit); } - - - /** Expert: returns an IndexReader reading the index in the given - * {@link IndexCommit} and termInfosIndexDivisor. - * @param commit the commit point to open - * @param termInfosIndexDivisor Subsamples which indexed - * terms are loaded into RAM. This has the same effect as {@link - * IndexWriterConfig#setTermIndexInterval} except that setting - * must be done at indexing time while this setting can be - * set per reader. When set to N, then one in every - * N*termIndexInterval terms in the index is loaded into - * memory. By setting this to a value > 1 you can reduce - * memory usage, at the expense of higher latency when - * loading a TermInfo. The default value is 1. Set this - * to -1 to skip loading the terms index entirely. - * @throws CorruptIndexException if the index is corrupt - * @throws IOException if there is a low-level IO error + + /** + * Expert: returns an IndexReader reading the index in the given + * {@link IndexCommit} and termInfosIndexDivisor. + * + * @param commit + * the commit point to open + * @param termInfosIndexDivisor + * Subsamples which indexed terms are loaded into RAM. This has the + * same effect as {@link IndexWriterConfig#setTermIndexInterval} + * except that setting must be done at indexing time while this + * setting can be set per reader. When set to N, then one in every + * N*termIndexInterval terms in the index is loaded into memory. By + * setting this to a value > 1 you can reduce memory usage, at the + * expense of higher latency when loading a TermInfo. The default + * value is 1. Set this to -1 to skip loading the terms index + * entirely. + * @throws CorruptIndexException + * if the index is corrupt + * @throws IOException + * if there is a low-level IO error * @deprecated Use {@link DirectoryReader#open(IndexCommit,int)} */ @Deprecated - public static DirectoryReader open(final IndexCommit commit, int termInfosIndexDivisor) throws CorruptIndexException, IOException { + public static DirectoryReader open(final IndexCommit commit, + int termInfosIndexDivisor) throws CorruptIndexException, IOException { return DirectoryReader.open(commit, termInfosIndexDivisor); } - - /** Retrieve term vectors for this document, or null if - * term vectors were not indexed. The returned Fields - * instance acts like a single-document inverted index - * (the docID will be 0). */ - public abstract Fields getTermVectors(int docID) - throws IOException; - - /** Retrieve term vector for this document and field, or - * null if term vectors were not indexed. The returned - * Fields instance acts like a single-document inverted - * index (the docID will be 0). */ - public final Terms getTermVector(int docID, String field) - throws IOException { + + /** + * Retrieve term vectors for this document, or null if term vectors were not + * indexed. The returned Fields instance acts like a single-document inverted + * index (the docID will be 0). + */ + public abstract Fields getTermVectors(int docID) throws IOException; + + /** + * Retrieve term vector for this document and field, or null if term vectors + * were not indexed. The returned Fields instance acts like a single-document + * inverted index (the docID will be 0). + */ + public final Terms getTermVector(int docID, String field) throws IOException { Fields vectors = getTermVectors(docID); if (vectors == null) { return null; } return vectors.terms(field); } - + /** Returns the number of documents in this index. */ public abstract int numDocs(); - - /** Returns one greater than the largest possible document number. - * This may be used to, e.g., determine how big to allocate an array which - * will have an element for every document number in an index. + + /** + * Returns one greater than the largest possible document number. This may be + * used to, e.g., determine how big to allocate an array which will have an + * element for every document number in an index. */ public abstract int maxDoc(); - + /** Returns the number of deleted documents. */ public final int numDeletedDocs() { return maxDoc() - numDocs(); } - - /** Expert: visits the fields of a stored document, for - * custom processing/loading of each field. If you - * simply want to load all fields, use {@link - * #document(int)}. If you want to load a subset, use - * {@link DocumentStoredFieldVisitor}. */ - public abstract void document(int docID, StoredFieldVisitor visitor) throws CorruptIndexException, IOException; /** + * Expert: visits the fields of a stored document, for custom + * processing/loading of each field. If you simply want to load all fields, + * use {@link #document(int)}. If you want to load a subset, use + * {@link DocumentStoredFieldVisitor}. + */ + public abstract void document(int docID, StoredFieldVisitor visitor) + throws CorruptIndexException, IOException; + + /** * Returns the stored fields of the nth - * Document in this index. This is just - * sugar for using {@link DocumentStoredFieldVisitor}. + * Document in this index. This is just sugar for using + * {@link DocumentStoredFieldVisitor}. *

    * NOTE: for performance reasons, this method does not check if the * requested document is deleted, and therefore asking for a deleted document * may yield unspecified results. Usually this is not required, however you - * can test if the doc is deleted by checking the {@link - * Bits} returned from {@link MultiFields#getLiveDocs}. - * - * NOTE: only the content of a field is returned, - * if that field was stored during indexing. Metadata - * like boost, omitNorm, IndexOptions, tokenized, etc., - * are not preserved. + * can test if the doc is deleted by checking the {@link Bits} returned from + * {@link MultiFields#getLiveDocs}. * - * @throws CorruptIndexException if the index is corrupt - * @throws IOException if there is a low-level IO error + * NOTE: only the content of a field is returned, if that field was + * stored during indexing. Metadata like boost, omitNorm, IndexOptions, + * tokenized, etc., are not preserved. + * + * @throws CorruptIndexException + * if the index is corrupt + * @throws IOException + * if there is a low-level IO error */ // TODO: we need a separate StoredField, so that the // Document returned here contains that class not // IndexableField - public final Document document(int docID) throws CorruptIndexException, IOException { + public final StoredDocument document(int docID) throws CorruptIndexException, + IOException { final DocumentStoredFieldVisitor visitor = new DocumentStoredFieldVisitor(); document(docID, visitor); return visitor.getDocument(); } - + /** - * Like {@link #document(int)} but only loads the specified - * fields. Note that this is simply sugar for {@link - * DocumentStoredFieldVisitor#DocumentStoredFieldVisitor(Set)}. + * Like {@link #document(int)} but only loads the specified fields. Note that + * this is simply sugar for + * {@link DocumentStoredFieldVisitor#DocumentStoredFieldVisitor(Set)}. */ - public final Document document(int docID, Set fieldsToLoad) throws CorruptIndexException, IOException { - final DocumentStoredFieldVisitor visitor = new DocumentStoredFieldVisitor(fieldsToLoad); + public final StoredDocument document(int docID, Set fieldsToLoad) + throws CorruptIndexException, IOException { + final DocumentStoredFieldVisitor visitor = new DocumentStoredFieldVisitor( + fieldsToLoad); document(docID, visitor); return visitor.getDocument(); } - + /** Returns true if any documents have been deleted */ public abstract boolean hasDeletions(); - + /** - * Closes files associated with this index. - * Also saves any new deletions to disk. - * No other methods should be called after this has been called. - * @throws IOException if there is a low-level IO error + * Closes files associated with this index. Also saves any new deletions to + * disk. No other methods should be called after this has been called. + * + * @throws IOException + * if there is a low-level IO error */ public final synchronized void close() throws IOException { if (!closed) { @@ -470,59 +518,65 @@ /** Implements close. */ protected abstract void doClose() throws IOException; - + /** * Expert: Returns a the root {@link IndexReaderContext} for this * {@link IndexReader}'s sub-reader tree. Iff this reader is composed of sub * readers ,ie. this reader being a composite reader, this method returns a - * {@link CompositeReaderContext} holding the reader's direct children as well as a - * view of the reader tree's atomic leaf contexts. All sub- + * {@link CompositeReaderContext} holding the reader's direct children as well + * as a view of the reader tree's atomic leaf contexts. All sub- * {@link IndexReaderContext} instances referenced from this readers top-level * context are private to this reader and are not shared with another context * tree. For example, IndexSearcher uses this API to drive searching by one * atomic leaf reader at a time. If this reader is not composed of child * readers, this method returns an {@link AtomicReaderContext}. *

    - * Note: Any of the sub-{@link CompositeReaderContext} instances reference from this - * top-level context holds a null {@link CompositeReaderContext#leaves()} - * reference. Only the top-level context maintains the convenience leaf-view - * for performance reasons. + * Note: Any of the sub-{@link CompositeReaderContext} instances reference + * from this top-level context holds a null + * {@link CompositeReaderContext#leaves()} reference. Only the top-level + * context maintains the convenience leaf-view for performance reasons. * * @lucene.experimental */ public abstract IndexReaderContext getTopReaderContext(); - - /** Expert: Returns a key for this IndexReader, so FieldCache/CachingWrapperFilter can find - * it again. - * This key must not have equals()/hashCode() methods, so "equals" means "identical". */ + + /** + * Expert: Returns a key for this IndexReader, so + * FieldCache/CachingWrapperFilter can find it again. This key must not have + * equals()/hashCode() methods, so "equals" means + * "identical". + */ public Object getCoreCacheKey() { // Don't can ensureOpen since FC calls this (to evict) // on close return this; } - - /** Expert: Returns a key for this IndexReader that also includes deletions, - * so FieldCache/CachingWrapperFilter can find it again. - * This key must not have equals()/hashCode() methods, so "equals" means "identical". */ + + /** + * Expert: Returns a key for this IndexReader that also includes deletions, so + * FieldCache/CachingWrapperFilter can find it again. This key must not have + * equals()/hashCode() methods, so "equals" means + * "identical". + */ public Object getCombinedCoreAndDeletesKey() { // Don't can ensureOpen since FC calls this (to evict) // on close return this; } - /** Returns the number of documents containing the - * term. This method returns 0 if the term or - * field does not exists. This method does not take into - * account deleted documents that have not yet been merged - * away. */ + /** + * Returns the number of documents containing the term. This + * method returns 0 if the term or field does not exists. This method does not + * take into account deleted documents that have not yet been merged away. + */ public final int docFreq(Term term) throws IOException { return docFreq(term.field(), term.bytes()); } - - /** Returns the number of documents containing the - * term. This method returns 0 if the term or - * field does not exists. This method does not take into - * account deleted documents that have not yet been merged - * away. */ + + /** + * Returns the number of documents containing the term. This + * method returns 0 if the term or field does not exists. This method does not + * take into account deleted documents that have not yet been merged away. + */ public abstract int docFreq(String field, BytesRef term) throws IOException; } Index: lucene/core/src/java/org/apache/lucene/index/IndexWriter.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/IndexWriter.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/index/IndexWriter.java (working copy) @@ -1011,7 +1011,7 @@ * @throws CorruptIndexException if the index is corrupt * @throws IOException if there is a low-level IO error */ - public void addDocument(Iterable doc) throws CorruptIndexException, IOException { + public void addDocument(Document doc) throws CorruptIndexException, IOException { addDocument(doc, analyzer); } @@ -1030,7 +1030,7 @@ * @throws CorruptIndexException if the index is corrupt * @throws IOException if there is a low-level IO error */ - public void addDocument(Iterable doc, Analyzer analyzer) throws CorruptIndexException, IOException { + public void addDocument(Document doc, Analyzer analyzer) throws CorruptIndexException, IOException { updateDocument(null, doc, analyzer); } @@ -1068,7 +1068,7 @@ * * @lucene.experimental */ - public void addDocuments(Iterable> docs) throws CorruptIndexException, IOException { + public void addDocuments(Iterable docs) throws CorruptIndexException, IOException { addDocuments(docs, analyzer); } @@ -1083,7 +1083,7 @@ * * @lucene.experimental */ - public void addDocuments(Iterable> docs, Analyzer analyzer) throws CorruptIndexException, IOException { + public void addDocuments(Iterable docs, Analyzer analyzer) throws CorruptIndexException, IOException { updateDocuments(null, docs, analyzer); } @@ -1100,7 +1100,7 @@ * * @lucene.experimental */ - public void updateDocuments(Term delTerm, Iterable> docs) throws CorruptIndexException, IOException { + public void updateDocuments(Term delTerm, Iterable docs) throws CorruptIndexException, IOException { updateDocuments(delTerm, docs, analyzer); } @@ -1118,7 +1118,7 @@ * * @lucene.experimental */ - public void updateDocuments(Term delTerm, Iterable> docs, Analyzer analyzer) throws CorruptIndexException, IOException { + public void updateDocuments(Term delTerm, Iterable docs, Analyzer analyzer) throws CorruptIndexException, IOException { ensureOpen(); try { boolean success = false; @@ -1243,7 +1243,7 @@ * @throws CorruptIndexException if the index is corrupt * @throws IOException if there is a low-level IO error */ - public void updateDocument(Term term, Iterable doc) throws CorruptIndexException, IOException { + public void updateDocument(Term term, Document doc) throws CorruptIndexException, IOException { ensureOpen(); updateDocument(term, doc, getAnalyzer()); } @@ -1266,7 +1266,7 @@ * @throws CorruptIndexException if the index is corrupt * @throws IOException if there is a low-level IO error */ - public void updateDocument(Term term, Iterable doc, Analyzer analyzer) + public void updateDocument(Term term, Document doc, Analyzer analyzer) throws CorruptIndexException, IOException { ensureOpen(); try { Index: lucene/core/src/java/org/apache/lucene/index/Norm.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/Norm.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/index/Norm.java (working copy) @@ -26,6 +26,7 @@ import org.apache.lucene.document.PackedLongDocValuesField; import org.apache.lucene.document.ShortDocValuesField; import org.apache.lucene.document.SortedBytesDocValuesField; +import org.apache.lucene.document.StoredField; import org.apache.lucene.document.StraightBytesDocValuesField; import org.apache.lucene.index.DocValues.Type; import org.apache.lucene.search.similarities.Similarity; @@ -43,13 +44,13 @@ * @lucene.internal */ public final class Norm { - private Field field; + private StoredField field; private BytesRef spare; /** * Returns the {@link IndexableField} representation for this norm */ - public IndexableField field() { + public StoredField field() { return field; } Index: lucene/core/src/java/org/apache/lucene/index/NormsConsumerPerField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/NormsConsumerPerField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/index/NormsConsumerPerField.java (working copy) @@ -51,10 +51,10 @@ similarity.computeNorm(fieldState, norm); if (norm.type() != null) { - IndexableField field = norm.field(); + StorableField field = norm.field(); // some similarity might not compute any norms DocValuesConsumer consumer = getConsumer(norm.type()); - consumer.add(docState.docID, field); + consumer.add(docState.docID, (StorableField) field); } } } Index: lucene/core/src/java/org/apache/lucene/index/PersistentSnapshotDeletionPolicy.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/PersistentSnapshotDeletionPolicy.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/index/PersistentSnapshotDeletionPolicy.java (working copy) @@ -26,6 +26,8 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.FieldType; +import org.apache.lucene.document.StoredDocument; +import org.apache.lucene.document.StoredField; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.store.Directory; import org.apache.lucene.store.LockObtainFailedException; @@ -68,12 +70,12 @@ int numDocs = r.numDocs(); // index is allowed to have exactly one document or 0. if (numDocs == 1) { - Document doc = r.document(r.maxDoc() - 1); + StoredDocument doc = r.document(r.maxDoc() - 1); if (doc.getField(SNAPSHOTS_ID) == null) { throw new IllegalStateException("directory is not a valid snapshots store!"); } doc.removeField(SNAPSHOTS_ID); - for (IndexableField f : doc) { + for (StorableField f : doc) { snapshots.put(f.name(), f.stringValue()); } } else if (numDocs != 0) { @@ -186,14 +188,12 @@ private void persistSnapshotInfos(String id, String segment) throws IOException { writer.deleteAll(); Document d = new Document(); - FieldType ft = new FieldType(); - ft.setStored(true); - d.add(new Field(SNAPSHOTS_ID, "", ft)); + d.add(new StoredField(SNAPSHOTS_ID, "")); for (Entry e : super.getSnapshots().entrySet()) { - d.add(new Field(e.getKey(), e.getValue(), ft)); + d.add(new StoredField(e.getKey(), e.getValue())); } if (id != null) { - d.add(new Field(id, segment, ft)); + d.add(new StoredField(id, segment)); } writer.addDocument(d); writer.commit(); Index: lucene/core/src/java/org/apache/lucene/index/StorableField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/StorableField.java (revision 0) +++ lucene/core/src/java/org/apache/lucene/index/StorableField.java (working copy) @@ -0,0 +1,43 @@ +package org.apache.lucene.index; + +import java.io.Reader; + +import org.apache.lucene.util.BytesRef; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public interface StorableField { + + /** Field name */ + public String name(); + + /** Field type */ + public StorableFieldType fieldType(); + + /** Non-null if this field has a binary value */ + public BytesRef binaryValue(); + + /** Non-null if this field has a string value */ + public String stringValue(); + + /** Non-null if this field has a Reader value */ + public Reader readerValue(); + + /** Non-null if this field has a numeric value */ + public Number numericValue(); +} Index: lucene/core/src/java/org/apache/lucene/index/StorableFieldType.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/StorableFieldType.java (revision 0) +++ lucene/core/src/java/org/apache/lucene/index/StorableFieldType.java (working copy) @@ -0,0 +1,25 @@ +package org.apache.lucene.index; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public interface StorableFieldType { + + /** DocValues type; if non-null then the field's value + * will be indexed into docValues */ + public DocValues.Type docValueType(); +} Index: lucene/core/src/java/org/apache/lucene/index/StoredFieldsConsumer.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/StoredFieldsConsumer.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/index/StoredFieldsConsumer.java (working copy) @@ -44,12 +44,12 @@ } private int numStoredFields; - private IndexableField[] storedFields; + private StorableField[] storedFields; private FieldInfo[] fieldInfos; public void reset() { numStoredFields = 0; - storedFields = new IndexableField[1]; + storedFields = new StorableField[1]; fieldInfos = new FieldInfo[1]; } @@ -125,10 +125,10 @@ assert docWriter.writer.testPoint("StoredFieldsWriter.finishDocument end"); } - public void addField(IndexableField field, FieldInfo fieldInfo) throws IOException { + public void addField(StorableField field, FieldInfo fieldInfo) throws IOException { if (numStoredFields == storedFields.length) { int newSize = ArrayUtil.oversize(numStoredFields + 1, RamUsageEstimator.NUM_BYTES_OBJECT_REF); - IndexableField[] newArray = new IndexableField[newSize]; + StorableField[] newArray = new StorableField[newSize]; System.arraycopy(storedFields, 0, newArray, 0, numStoredFields); storedFields = newArray; Index: lucene/core/src/java/org/apache/lucene/index/TermVectorsConsumerPerField.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/TermVectorsConsumerPerField.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/index/TermVectorsConsumerPerField.java (working copy) @@ -61,7 +61,7 @@ for(int i=0;i.getIndexReader().document(docID) */ - public Document doc(int docID) throws CorruptIndexException, IOException { + public StoredDocument doc(int docID) throws CorruptIndexException, IOException { return reader.document(docID); } @@ -190,7 +191,7 @@ } /** Sugar for .getIndexReader().document(docID, fieldsToLoad) */ - public final Document document(int docID, Set fieldsToLoad) throws CorruptIndexException, IOException { + public final StoredDocument document(int docID, Set fieldsToLoad) throws CorruptIndexException, IOException { return reader.document(docID, fieldsToLoad); } Index: lucene/core/src/java/org/apache/lucene/search/NRTManager.java =================================================================== --- lucene/core/src/java/org/apache/lucene/search/NRTManager.java (revision 1340366) +++ lucene/core/src/java/org/apache/lucene/search/NRTManager.java (working copy) @@ -28,6 +28,7 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.Document; import org.apache.lucene.index.IndexReader; // javadocs import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexableField; @@ -154,25 +155,25 @@ this.writer = writer; } - public long updateDocument(Term t, Iterable d, Analyzer a) throws IOException { + public long updateDocument(Term t, Document d, Analyzer a) throws IOException { writer.updateDocument(t, d, a); // Return gen as of when indexing finished: return indexingGen.get(); } - public long updateDocument(Term t, Iterable d) throws IOException { + public long updateDocument(Term t, Document d) throws IOException { writer.updateDocument(t, d); // Return gen as of when indexing finished: return indexingGen.get(); } - public long updateDocuments(Term t, Iterable> docs, Analyzer a) throws IOException { + public long updateDocuments(Term t, Iterable docs, Analyzer a) throws IOException { writer.updateDocuments(t, docs, a); // Return gen as of when indexing finished: return indexingGen.get(); } - public long updateDocuments(Term t, Iterable> docs) throws IOException { + public long updateDocuments(Term t, Iterable docs) throws IOException { writer.updateDocuments(t, docs); // Return gen as of when indexing finished: return indexingGen.get(); @@ -208,25 +209,25 @@ return indexingGen.get(); } - public long addDocument(Iterable d, Analyzer a) throws IOException { + public long addDocument(Document d, Analyzer a) throws IOException { writer.addDocument(d, a); // Return gen as of when indexing finished: return indexingGen.get(); } - public long addDocuments(Iterable> docs, Analyzer a) throws IOException { + public long addDocuments(Iterable docs, Analyzer a) throws IOException { writer.addDocuments(docs, a); // Return gen as of when indexing finished: return indexingGen.get(); } - public long addDocument(Iterable d) throws IOException { + public long addDocument(Document d) throws IOException { writer.addDocument(d); // Return gen as of when indexing finished: return indexingGen.get(); } - public long addDocuments(Iterable> docs) throws IOException { + public long addDocuments(Iterable docs) throws IOException { writer.addDocuments(docs); // Return gen as of when indexing finished: return indexingGen.get();