LUCENE-3108: convert Float on load instead of converting for every lookup through FloatsBuffer

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/branches/docvalues@1126430 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Simon Willnauer 2011-05-23 10:58:45 +00:00
parent 8f13a775b5
commit cb7583bcb9
2 changed files with 31 additions and 24 deletions

View File

@ -18,8 +18,6 @@ package org.apache.lucene.index.values;
*/ */
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
@ -262,33 +260,41 @@ public class Floats {
*/ */
@Override @Override
public Source load() throws IOException { public Source load() throws IOException {
/* /* we always read BIG_ENDIAN here since the writer uses
* the allocated byteBuffer always uses BIG_ENDIAN here * DataOutput#writeInt() / writeLong() we can simply read the ints / longs
* and since the writer uses DataOutput#writeInt() / writeLong() * back in using readInt / readLong */
* we can allways assume BIGE_ENDIAN final IndexInput indexInput = (IndexInput) datIn.clone();
*/
final ByteBuffer buffer = ByteBuffer.allocate(precisionBytes * maxDoc);
IndexInput indexInput = (IndexInput) datIn.clone();
indexInput.seek(CodecUtil.headerLength(CODEC_NAME)); indexInput.seek(CodecUtil.headerLength(CODEC_NAME));
// skip precision: // skip precision:
indexInput.readByte(); indexInput.readByte();
assert buffer.hasArray() : "Buffer must support Array"; if (precisionBytes == 4) {
final byte[] arr = buffer.array(); final float[] values = new float[(4 * maxDoc) >> 2];
indexInput.readBytes(arr, 0, arr.length); assert values.length == maxDoc;
return precisionBytes == 4 ? new Source4(buffer) : new Source8(buffer); for (int i = 0; i < values.length; i++) {
values[i] = Float.intBitsToFloat(indexInput.readInt());
}
return new Source4(values);
} else {
final double[] values = new double[(8 * maxDoc) >> 3];
assert values.length == maxDoc;
for (int i = 0; i < values.length; i++) {
values[i] = Double.longBitsToDouble(indexInput.readLong());
}
return new Source8(values);
}
} }
private class Source4 extends Source { private class Source4 extends Source {
private final FloatBuffer values; private final float[] values;
Source4(ByteBuffer buffer) { Source4(final float[] values ) throws IOException {
values = buffer.asFloatBuffer(); this.values = values;
missingValue.doubleValue = Float.NEGATIVE_INFINITY; missingValue.doubleValue = Float.NEGATIVE_INFINITY;
} }
@Override @Override
public double getFloat(int docID) { public double getFloat(int docID) {
return values.get(docID); return values[docID];
} }
@Override @Override
@ -318,17 +324,16 @@ public class Floats {
} }
private class Source8 extends Source { private class Source8 extends Source {
private final DoubleBuffer values; private final double[] values;
Source8(ByteBuffer buffer) { Source8(final double[] values) throws IOException {
values = buffer.asDoubleBuffer(); this.values = values;
missingValue.doubleValue = Double.NEGATIVE_INFINITY; missingValue.doubleValue = Double.NEGATIVE_INFINITY;
} }
@Override @Override
public double getFloat(int docID) { public double getFloat(int docID) {
return values.get(docID); return values[docID];
} }
@Override @Override

View File

@ -298,7 +298,7 @@ public class TestDocValuesIndexing extends LuceneTestCase {
for (int i = 0; i < base; i++) { for (int i = 0; i < base; i++) {
double value = floats.getFloat(i); double value = floats.getFloat(i);
assertEquals(" floats failed for doc: " + i + " base: " + base, assertEquals(val + " failed for doc: " + i + " base: " + base,
missing.doubleValue, value, 0.0d); missing.doubleValue, value, 0.0d);
} }
DocValuesEnum floatEnum = getValuesEnum(floatReader); DocValuesEnum floatEnum = getValuesEnum(floatReader);
@ -528,9 +528,11 @@ public class TestDocValuesIndexing extends LuceneTestCase {
valField.setInt(i); valField.setInt(i);
break; break;
case FLOAT_32: case FLOAT_32:
case FLOAT_64:
valField.setFloat(2.0f * i); valField.setFloat(2.0f * i);
break; break;
case FLOAT_64:
valField.setFloat(2.0d * i);
break;
default: default:
fail("unexpected value " + value); fail("unexpected value " + value);
} }