Index: java/org/apache/lucene/document/AbstractField.java =================================================================== --- java/org/apache/lucene/document/AbstractField.java (revision 636251) +++ java/org/apache/lucene/document/AbstractField.java (working copy) @@ -36,6 +36,9 @@ protected float boost = 1.0f; // the one and only data object for all different kind of field values protected Object fieldsData = null; + //length/offset for all primitive types + protected int dataLength; + protected int dataOffset; protected AbstractField() { @@ -199,7 +202,30 @@ /** True iff the value of the filed is stored as binary */ public final boolean isBinary() { return isBinary; } + + /** + * @returns reference to the Field value as byte[] + */ + public byte[] getBinaryValue() { return fieldsData instanceof byte[] ? (byte[])fieldsData : null; } + /** + * Returns length of byte[] segment that is used as value, if Field is not binary + * returned value is undefined + * @returns length of byte[] segment that represents this Field value + */ + public int getLength() { + return dataLength; + } + + /** + * Returns offset into byte[] segment that is used as value, if Field is not binary + * returned value is undefined + * @returns index of the first character in byte[] segment that represents this Field value + */ + public int getOffset() { + return dataOffset; + } + /** True if norms are omitted for this indexed field */ public boolean getOmitNorms() { return omitNorms; } Index: java/org/apache/lucene/document/Field.java =================================================================== --- java/org/apache/lucene/document/Field.java (revision 636251) +++ java/org/apache/lucene/document/Field.java (working copy) @@ -147,8 +147,18 @@ /** The value of the field in Binary, or null. If null, the Reader value, * String value, or TokenStream value is used. Exactly one of stringValue(), - * readerValue(), binaryValue(), and tokenStreamValue() must be set. */ - public byte[] binaryValue() { return isBinary ? (byte[])fieldsData : null; } + * readerValue(), binaryValue(), and tokenStreamValue() must be set. + * @deprecated use {@link AbstractField#getBinaryValue()} + */ + public byte[] binaryValue() { + if(!isBinary) return null; + final byte[] data = (byte[])fieldsData; + if(dataOffset==0 && data.length==dataLength) return data; //Optimization + + final byte[] ret = new byte[dataLength]; + System.arraycopy(data, dataOffset, ret, 0, dataLength); + return ret; + } /** The value of the field as a TokesStream, or null. If null, the Reader value, * String value, or binary value is used. Exactly one of stringValue(), @@ -182,9 +192,19 @@ /** Expert: change the value of this field. See setValue(String). */ public void setValue(byte[] value) { fieldsData = value; + dataLength = value.length; + dataOffset = 0; } /** Expert: change the value of this field. See setValue(String). */ + public void setValue(byte[] value, int offset, int length) { + fieldsData = value; + dataLength = length; + dataOffset = offset; + } + + + /** Expert: change the value of this field. See setValue(String). */ public void setValue(TokenStream value) { fieldsData = value; } @@ -403,6 +423,8 @@ this.isTokenized = false; this.isBinary = true; + this.dataLength = value.length; + this.dataOffset = 0; setStoreTermVector(TermVector.NO); } Index: java/org/apache/lucene/index/FieldsReader.java =================================================================== --- java/org/apache/lucene/index/FieldsReader.java (revision 636251) +++ java/org/apache/lucene/index/FieldsReader.java (working copy) @@ -426,12 +426,19 @@ } else { fieldsData = b; } + isBinary = true; } catch (IOException e) { throw new FieldReaderException(e); } } - return isBinary ? (byte[]) fieldsData : null; + dataOffset = 0; + if(isBinary){ + byte[] x = (byte[]) fieldsData; + dataLength = x.length; + return x; + } + return null; } /** The value of the field as a Reader, or null. If null, the String value, Index: java/org/apache/lucene/index/FieldsWriter.java =================================================================== --- java/org/apache/lucene/index/FieldsWriter.java (revision 636251) +++ java/org/apache/lucene/index/FieldsWriter.java (working copy) @@ -21,6 +21,7 @@ import java.util.Iterator; import java.util.zip.Deflater; +import org.apache.lucene.document.AbstractField; import org.apache.lucene.document.Document; import org.apache.lucene.document.Fieldable; import org.apache.lucene.store.Directory; @@ -97,31 +98,56 @@ if (field.isCompressed()) { // compression is enabled for the current field byte[] data = null; - + final int len; + final int offset; if (disableCompression) { // optimized case for merging, the data // is already compressed - data = field.binaryValue(); + final AbstractField f = (AbstractField) field;// FieldsReader.FieldForMerge is AbstracField + data = f.getBinaryValue(); + len = f.getLength(); + offset = f.getOffset(); } else { // check if it is a binary field if (field.isBinary()) { - data = compress(field.binaryValue()); + if(field instanceof AbstractField){ + final AbstractField f = (AbstractField) field; + data = compress(f.getBinaryValue(), f.getOffset(), f.getLength()); + } else{ + final byte[] buf = field.binaryValue(); + data = compress(buf, 0, buf.length); + } + } else { - data = compress(field.stringValue().getBytes("UTF-8")); + byte x[] = field.stringValue().getBytes("UTF-8"); + data = compress(x, 0,x.length); } + len = data.length; + offset = 0; } - final int len = data.length; + fieldsStream.writeVInt(len); - fieldsStream.writeBytes(data, len); + fieldsStream.writeBytes(data, offset, len); } else { // compression is disabled for the current field if (field.isBinary()) { - byte[] data = field.binaryValue(); - final int len = data.length; + final byte[] data; + final int len; + final int offset; + if(field instanceof AbstractField){ + final AbstractField f = (AbstractField) field; + data = f.getBinaryValue(); + len = f.getLength(); + offset = f.getOffset(); + } else{ + data = field.binaryValue(); + len = data.length; + offset = 0; + } fieldsStream.writeVInt(len); - fieldsStream.writeBytes(data, len); + fieldsStream.writeBytes(data, offset, len); } else { fieldsStream.writeString(field.stringValue()); @@ -165,14 +191,14 @@ } } - private final byte[] compress (byte[] input) { + private final byte[] compress (byte[] input, int offset, int length) { // Create the compressor with highest level of compression Deflater compressor = new Deflater(); compressor.setLevel(Deflater.BEST_COMPRESSION); // Give the compressor the data to compress - compressor.setInput(input); + compressor.setInput(input,offset, length); compressor.finish(); /* @@ -181,7 +207,7 @@ * there is no guarantee that the compressed data will be smaller than * the uncompressed data. */ - ByteArrayOutputStream bos = new ByteArrayOutputStream(input.length); + ByteArrayOutputStream bos = new ByteArrayOutputStream(length); // Compress the data byte[] buf = new byte[1024];