LUCENE-7475: Remove one layer of abstraction in the Lucene70 norms impl.

This commit is contained in:
Adrien Grand 2016-10-26 10:39:01 +02:00
parent ecfbe51c94
commit 5394d29fca
1 changed files with 136 additions and 101 deletions

View File

@ -95,8 +95,78 @@ final class Lucene70NormsProducer extends NormsProducer {
long normsOffset; long normsOffset;
} }
static abstract class LongValues { static abstract class DenseNormsIterator extends NumericDocValues {
abstract long get(int index) throws IOException;
final int maxDoc;
int doc = -1;
DenseNormsIterator(int maxDoc) {
this.maxDoc = maxDoc;
}
@Override
public int docID() {
return doc;
}
@Override
public int nextDoc() throws IOException {
return advance(doc + 1);
}
@Override
public int advance(int target) throws IOException {
if (target >= maxDoc) {
return doc = NO_MORE_DOCS;
}
return doc = target;
}
@Override
public boolean advanceExact(int target) throws IOException {
this.doc = target;
return true;
}
@Override
public long cost() {
return maxDoc;
}
}
static abstract class SparseNormsIterator extends NumericDocValues {
final IndexedDISI disi;
SparseNormsIterator(IndexedDISI disi) {
this.disi = disi;
}
@Override
public int docID() {
return disi.docID();
}
@Override
public int nextDoc() throws IOException {
return disi.nextDoc();
}
@Override
public int advance(int target) throws IOException {
return disi.advance(target);
}
@Override
public boolean advanceExact(int target) throws IOException {
return disi.advanceExact(target);
}
@Override
public long cost() {
return disi.cost();
}
} }
private void readFields(IndexInput meta, FieldInfos infos) throws IOException { private void readFields(IndexInput meta, FieldInfos infos) throws IOException {
@ -131,122 +201,87 @@ final class Lucene70NormsProducer extends NormsProducer {
return DocValues.emptyNumeric(); return DocValues.emptyNumeric();
} else if (entry.docsWithFieldOffset == -1) { } else if (entry.docsWithFieldOffset == -1) {
// dense // dense
final LongValues normValues = getNormValues(entry);
return new NumericDocValues() {
int doc = -1;
@Override
public long longValue() throws IOException {
return normValues.get(doc);
}
@Override
public int docID() {
return doc;
}
@Override
public int nextDoc() throws IOException {
return advance(doc + 1);
}
@Override
public int advance(int target) throws IOException {
if (target >= maxDoc) {
return doc = NO_MORE_DOCS;
}
return doc = target;
}
@Override
public boolean advanceExact(int target) throws IOException {
this.doc = target;
return true;
}
@Override
public long cost() {
return maxDoc;
}
};
} else {
// sparse
final LongValues normValues = getNormValues(entry);
final IndexedDISI disi = new IndexedDISI(data, entry.docsWithFieldOffset, entry.docsWithFieldLength, entry.numDocsWithField);
return new NumericDocValues() {
@Override
public int advance(int target) throws IOException {
return disi.advance(target);
}
@Override
public boolean advanceExact(int target) throws IOException {
return disi.advanceExact(target);
}
@Override
public int nextDoc() throws IOException {
return disi.nextDoc();
}
@Override
public int docID() {
return disi.docID();
}
@Override
public long cost() {
return entry.numDocsWithField;
}
@Override
public long longValue() throws IOException {
return normValues.get(disi.index());
}
};
}
}
private LongValues getNormValues(NormsEntry entry) throws IOException {
if (entry.bytesPerNorm == 0) { if (entry.bytesPerNorm == 0) {
return new LongValues() { return new DenseNormsIterator(maxDoc) {
@Override @Override
long get(int index) { public long longValue() throws IOException {
return entry.normsOffset; return entry.normsOffset;
} }
}; };
} else { }
final RandomAccessInput slice = data.randomAccessSlice(entry.normsOffset, entry.numDocsWithField * (long) entry.bytesPerNorm); final RandomAccessInput slice = data.randomAccessSlice(entry.normsOffset, entry.numDocsWithField * (long) entry.bytesPerNorm);
switch (entry.bytesPerNorm) { switch (entry.bytesPerNorm) {
case 1: case 1:
return new LongValues() { return new DenseNormsIterator(maxDoc) {
@Override @Override
long get(int index) throws IOException { public long longValue() throws IOException {
return slice.readByte(index); return slice.readByte(doc);
} }
}; };
case 2: case 2:
return new LongValues() { return new DenseNormsIterator(maxDoc) {
@Override @Override
long get(int index) throws IOException { public long longValue() throws IOException {
return slice.readShort(((long) index) << 1); return slice.readShort(((long) doc) << 1);
} }
}; };
case 4: case 4:
return new LongValues() { return new DenseNormsIterator(maxDoc) {
@Override @Override
long get(int index) throws IOException { public long longValue() throws IOException {
return slice.readInt(((long) index) << 2); return slice.readInt(((long) doc) << 2);
} }
}; };
case 8: case 8:
return new LongValues() { return new DenseNormsIterator(maxDoc) {
@Override @Override
long get(int index) throws IOException { public long longValue() throws IOException {
return slice.readLong(((long) index) << 3); return slice.readLong(((long) doc) << 3);
}
};
default:
// should not happen, we already validate bytesPerNorm in readFields
throw new AssertionError();
}
} else {
// sparse
final IndexedDISI disi = new IndexedDISI(data, entry.docsWithFieldOffset, entry.docsWithFieldLength, entry.numDocsWithField);
if (entry.bytesPerNorm == 0) {
return new SparseNormsIterator(disi) {
@Override
public long longValue() throws IOException {
return entry.normsOffset;
}
};
}
final RandomAccessInput slice = data.randomAccessSlice(entry.normsOffset, entry.numDocsWithField * (long) entry.bytesPerNorm);
switch (entry.bytesPerNorm) {
case 1:
return new SparseNormsIterator(disi) {
@Override
public long longValue() throws IOException {
return slice.readByte(disi.index());
}
};
case 2:
return new SparseNormsIterator(disi) {
@Override
public long longValue() throws IOException {
return slice.readShort(((long) disi.index()) << 1);
}
};
case 4:
return new SparseNormsIterator(disi) {
@Override
public long longValue() throws IOException {
return slice.readInt(((long) disi.index()) << 2);
}
};
case 8:
return new SparseNormsIterator(disi) {
@Override
public long longValue() throws IOException {
return slice.readLong(((long) disi.index()) << 3);
} }
}; };
default: default: