Simplify NestedFieldComparators for numerics

The average and sum comparators basically share the same code which is
copy-past today. We can simplify this into a base class which reduces
code duplication and prevents copy-paste bugs.
This commit is contained in:
Simon Willnauer 2013-09-16 21:40:08 +02:00
parent cabbf7805b
commit 1499881c36
1 changed files with 49 additions and 75 deletions

View File

@ -242,13 +242,11 @@ abstract class NestedFieldComparator extends FieldComparator {
int cmp1 = wrappedComparator.compareBottom(nestedDoc); int cmp1 = wrappedComparator.compareBottom(nestedDoc);
if (cmp1 < 0) { if (cmp1 < 0) {
return cmp1; return cmp1;
} else { } else if (cmp1 == 0) {
if (cmp1 == 0) {
cmp = 0; cmp = 0;
} }
} }
} }
}
@Override @Override
public void copy(int slot, int rootDoc) throws IOException { public void copy(int slot, int rootDoc) throws IOException {
@ -279,131 +277,107 @@ abstract class NestedFieldComparator extends FieldComparator {
} }
final static class Sum extends NestedFieldComparator { static abstract class NumericNestedFieldComparatorBase extends NestedFieldComparator {
protected NumberComparatorBase numberComparator;
NumberComparatorBase wrappedComparator; NumericNestedFieldComparatorBase(NumberComparatorBase wrappedComparator, Filter rootDocumentsFilter, Filter innerDocumentsFilter, int spareSlot) {
super(wrappedComparator, rootDocumentsFilter, innerDocumentsFilter, spareSlot);
this.numberComparator = wrappedComparator;
}
@Override
public final int compareBottom(int rootDoc) throws IOException {
if (rootDoc == 0 || rootDocuments == null || innerDocuments == null) {
return compareBottomMissing(wrappedComparator);
}
final int prevRootDoc = rootDocuments.prevSetBit(rootDoc - 1);
int nestedDoc = innerDocuments.nextSetBit(prevRootDoc + 1);
if (nestedDoc >= rootDoc || nestedDoc == -1) {
return compareBottomMissing(wrappedComparator);
}
int counter = 1;
wrappedComparator.copy(spareSlot, nestedDoc);
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
while (nestedDoc > prevRootDoc && nestedDoc < rootDoc) {
onNested(spareSlot, nestedDoc);
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
counter++;
}
afterNested(spareSlot, counter);
return compare(bottomSlot, spareSlot);
}
@Override
public final void copy(int slot, int rootDoc) throws IOException {
if (rootDoc == 0 || rootDocuments == null || innerDocuments == null) {
copyMissing(wrappedComparator, slot);
return;
}
final int prevRootDoc = rootDocuments.prevSetBit(rootDoc - 1);
int nestedDoc = innerDocuments.nextSetBit(prevRootDoc + 1);
if (nestedDoc >= rootDoc || nestedDoc == -1) {
copyMissing(wrappedComparator, slot);
return;
}
int counter = 1;
wrappedComparator.copy(slot, nestedDoc);
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
while (nestedDoc > prevRootDoc && nestedDoc < rootDoc) {
onNested(slot, nestedDoc);
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
counter++;
}
afterNested(slot, counter);
}
protected abstract void onNested(int slot, int nestedDoc);
protected abstract void afterNested(int slot, int count);
@Override
public final FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
super.setNextReader(context);
numberComparator = (NumberComparatorBase) super.wrappedComparator;
return this;
}
}
final static class Sum extends NumericNestedFieldComparatorBase {
Sum(NumberComparatorBase wrappedComparator, Filter rootDocumentsFilter, Filter innerDocumentsFilter, int spareSlot) { Sum(NumberComparatorBase wrappedComparator, Filter rootDocumentsFilter, Filter innerDocumentsFilter, int spareSlot) {
super(wrappedComparator, rootDocumentsFilter, innerDocumentsFilter, spareSlot); super(wrappedComparator, rootDocumentsFilter, innerDocumentsFilter, spareSlot);
this.wrappedComparator = wrappedComparator;
} }
@Override @Override
public int compareBottom(int rootDoc) throws IOException { protected void onNested(int slot, int nestedDoc) {
if (rootDoc == 0 || rootDocuments == null || innerDocuments == null) { numberComparator.add(slot, nestedDoc);
return compareBottomMissing(wrappedComparator);
}
int prevRootDoc = rootDocuments.prevSetBit(rootDoc - 1);
int nestedDoc = innerDocuments.nextSetBit(prevRootDoc + 1);
if (nestedDoc >= rootDoc || nestedDoc == -1) {
return compareBottomMissing(wrappedComparator);
}
wrappedComparator.copy(spareSlot, nestedDoc);
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
while (nestedDoc > prevRootDoc && nestedDoc < rootDoc) {
wrappedComparator.add(spareSlot, nestedDoc);
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
}
return compare(bottomSlot, spareSlot);
} }
@Override @Override
public void copy(int slot, int rootDoc) throws IOException { protected void afterNested(int slot, int count) {
if (rootDoc == 0 || rootDocuments == null || innerDocuments == null) {
copyMissing(wrappedComparator, slot);
return;
}
int prevRootDoc = rootDocuments.prevSetBit(rootDoc - 1);
int nestedDoc = innerDocuments.nextSetBit(prevRootDoc + 1);
if (nestedDoc >= rootDoc || nestedDoc == -1) {
copyMissing(wrappedComparator, slot);
return;
}
wrappedComparator.copy(slot, nestedDoc);
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
while (nestedDoc > prevRootDoc && nestedDoc < rootDoc) {
wrappedComparator.add(slot, nestedDoc);
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
}
}
@Override
public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
super.setNextReader(context);
wrappedComparator = (NumberComparatorBase) super.wrappedComparator;
return this;
} }
} }
final static class Avg extends NestedFieldComparator { final static class Avg extends NumericNestedFieldComparatorBase {
NumberComparatorBase wrappedComparator;
Avg(NumberComparatorBase wrappedComparator, Filter rootDocumentsFilter, Filter innerDocumentsFilter, int spareSlot) { Avg(NumberComparatorBase wrappedComparator, Filter rootDocumentsFilter, Filter innerDocumentsFilter, int spareSlot) {
super(wrappedComparator, rootDocumentsFilter, innerDocumentsFilter, spareSlot); super(wrappedComparator, rootDocumentsFilter, innerDocumentsFilter, spareSlot);
this.wrappedComparator = wrappedComparator;
} }
@Override @Override
public int compareBottom(int rootDoc) throws IOException { protected void onNested(int slot, int nestedDoc) {
if (rootDoc == 0 || rootDocuments == null || innerDocuments == null) { numberComparator.add(slot, nestedDoc);
return 0;
}
int prevRootDoc = rootDocuments.prevSetBit(rootDoc - 1);
int nestedDoc = innerDocuments.nextSetBit(prevRootDoc + 1);
if (nestedDoc >= rootDoc || nestedDoc == -1) {
return compareBottomMissing(wrappedComparator);
}
int counter = 1;
wrappedComparator.copy(spareSlot, nestedDoc);
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
while (nestedDoc > prevRootDoc && nestedDoc < rootDoc) {
wrappedComparator.add(spareSlot, nestedDoc);
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
counter++;
}
wrappedComparator.divide(spareSlot, counter);
return compare(bottomSlot, spareSlot);
} }
@Override @Override
public void copy(int slot, int rootDoc) throws IOException { protected void afterNested(int slot, int count) {
if (rootDoc == 0 || rootDocuments == null || innerDocuments == null) { numberComparator.divide(slot, count);
copyMissing(wrappedComparator, slot);
return;
} }
int prevRootDoc = rootDocuments.prevSetBit(rootDoc - 1);
int nestedDoc = innerDocuments.nextSetBit(prevRootDoc + 1);
if (nestedDoc >= rootDoc || nestedDoc == -1) {
copyMissing(wrappedComparator, slot);
return;
}
int counter = 1;
wrappedComparator.copy(slot, nestedDoc);
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
while (nestedDoc > prevRootDoc && nestedDoc < rootDoc) {
wrappedComparator.add(slot, nestedDoc);
nestedDoc = innerDocuments.nextSetBit(nestedDoc + 1);
counter++;
}
wrappedComparator.divide(slot, counter);
}
@Override
public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
super.setNextReader(context);
wrappedComparator = (NumberComparatorBase) super.wrappedComparator;
return this;
}
} }
static final void copyMissing(FieldComparator<?> comparator, int slot) { static final void copyMissing(FieldComparator<?> comparator, int slot) {