clean up iterators / iterators bugs / style

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/branches/lucene4547@1440234 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2013-01-30 01:20:46 +00:00
parent 34634ff4ec
commit 3ecb5d8831
5 changed files with 207 additions and 125 deletions

View File

@ -406,6 +406,9 @@ public abstract class DocValuesConsumer implements Closeable {
@Override @Override
public BytesRef next() { public BytesRef next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return merger.mergedTerms.get(ordUpto++); return merger.mergedTerms.get(ordUpto++);
} }
}; };

View File

@ -21,6 +21,7 @@ import static org.apache.lucene.util.ByteBlockPool.BYTE_BLOCK_SIZE;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException;
import org.apache.lucene.codecs.DocValuesConsumer; import org.apache.lucene.codecs.DocValuesConsumer;
import org.apache.lucene.store.RAMFile; import org.apache.lucene.store.RAMFile;
@ -99,22 +100,32 @@ class BinaryDocValuesWriter extends DocValuesWriter {
@Override @Override
public void flush(SegmentWriteState state, DocValuesConsumer dvConsumer) throws IOException { public void flush(SegmentWriteState state, DocValuesConsumer dvConsumer) throws IOException {
final int maxDoc = state.segmentInfo.getDocCount(); final int maxDoc = state.segmentInfo.getDocCount();
final int size = addedValues;
dvConsumer.addBinaryField(fieldInfo, dvConsumer.addBinaryField(fieldInfo,
new Iterable<BytesRef>() { new Iterable<BytesRef>() {
@Override @Override
public Iterator<BytesRef> iterator() { public Iterator<BytesRef> iterator() {
return new Iterator<BytesRef>() { return new BytesIterator(maxDoc);
RAMInputStream bytesReader; }
AppendingLongBuffer.Iterator iter = lengths.iterator(); });
BytesRef value = new BytesRef(); }
@Override
public void abort() {
}
// iterates over the values we have in ram
private class BytesIterator implements Iterator<BytesRef> {
final BytesRef value = new BytesRef();
final AppendingLongBuffer.Iterator lengthsIterator = lengths.iterator();
final int size = lengths.size();
final int maxDoc;
final RAMInputStream bytesReader;
int upto; int upto;
{ BytesIterator(int maxDoc) {
this.maxDoc = maxDoc;
try { try {
bytesReader = new RAMInputStream("bogus", bytes); bytesReader = new RAMInputStream("BinaryDocValuesWriter", bytes);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -125,15 +136,13 @@ class BinaryDocValuesWriter extends DocValuesWriter {
return upto < maxDoc; return upto < maxDoc;
} }
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override @Override
public BytesRef next() { public BytesRef next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
if (upto < size) { if (upto < size) {
int length = (int) iter.next(); int length = (int) lengthsIterator.next();
value.grow(length); value.grow(length);
try { try {
bytesReader.readBytes(value.bytes, 0, length); bytesReader.readBytes(value.bytes, 0, length);
@ -147,12 +156,10 @@ class BinaryDocValuesWriter extends DocValuesWriter {
upto++; upto++;
return value; return value;
} }
};
}
});
}
@Override @Override
public void abort() { public void remove() {
throw new UnsupportedOperationException();
}
} }
} }

View File

@ -19,6 +19,7 @@ package org.apache.lucene.index;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException;
import org.apache.lucene.codecs.DocValuesConsumer; import org.apache.lucene.codecs.DocValuesConsumer;
import org.apache.lucene.util.Counter; import org.apache.lucene.util.Counter;
@ -75,27 +76,40 @@ class NumericDocValuesWriter extends DocValuesWriter {
dvConsumer.addNumericField(fieldInfo, dvConsumer.addNumericField(fieldInfo,
new Iterable<Number>() { new Iterable<Number>() {
@Override @Override
public Iterator<Number> iterator() { public Iterator<Number> iterator() {
return new Iterator<Number>() { return new NumericIterator(maxDoc);
}
});
}
@Override
public void abort() {
}
// iterates over the values we have in ram
private class NumericIterator implements Iterator<Number> {
final AppendingLongBuffer.Iterator iter = pending.iterator();
final int size = pending.size();
final int maxDoc;
int upto; int upto;
AppendingLongBuffer.Iterator iter = pending.iterator();
NumericIterator(int maxDoc) {
this.maxDoc = maxDoc;
}
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return upto < maxDoc; return upto < maxDoc;
} }
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override @Override
public Number next() { public Number next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
long value; long value;
if (upto < pending.size()) { if (upto < size) {
value = iter.next(); value = iter.next();
} else { } else {
value = 0; value = 0;
@ -104,12 +118,10 @@ class NumericDocValuesWriter extends DocValuesWriter {
// TODO: make reusable Number // TODO: make reusable Number
return value; return value;
} }
};
}
});
}
@Override @Override
public void abort() { public void remove() {
throw new UnsupportedOperationException();
}
} }
} }

View File

@ -21,6 +21,7 @@ import static org.apache.lucene.util.ByteBlockPool.BYTE_BLOCK_SIZE;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException;
import org.apache.lucene.codecs.DocValuesConsumer; import org.apache.lucene.codecs.DocValuesConsumer;
import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.ArrayUtil;
@ -110,11 +111,12 @@ class SortedDocValuesWriter extends DocValuesWriter {
emptyOrd = ord; emptyOrd = ord;
} }
} else { } else {
emptyOrd = -1; emptyOrd = -1; // nocommit: HUH? how can this possibly work?
} }
final int valueCount = hash.size(); final int valueCount = hash.size();
// nocommit: account for both sortedValues and ordMap as-we-go...
final int[] sortedValues = hash.sort(BytesRef.getUTF8SortedAsUnicodeComparator()); final int[] sortedValues = hash.sort(BytesRef.getUTF8SortedAsUnicodeComparator());
final int sortedValueRamUsage = RamUsageEstimator.NUM_BYTES_ARRAY_HEADER + RamUsageEstimator.NUM_BYTES_INT*valueCount; final int sortedValueRamUsage = RamUsageEstimator.NUM_BYTES_ARRAY_HEADER + RamUsageEstimator.NUM_BYTES_INT*valueCount;
final int[] ordMap = new int[valueCount]; final int[] ordMap = new int[valueCount];
@ -131,27 +133,7 @@ class SortedDocValuesWriter extends DocValuesWriter {
new Iterable<BytesRef>() { new Iterable<BytesRef>() {
@Override @Override
public Iterator<BytesRef> iterator() { public Iterator<BytesRef> iterator() {
return new Iterator<BytesRef>() { return new ValuesIterator(sortedValues, valueCount);
int ordUpto;
BytesRef scratch = new BytesRef();
@Override
public boolean hasNext() {
return ordUpto < valueCount;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public BytesRef next() {
hash.get(sortedValues[ordUpto], scratch);
ordUpto++;
return scratch;
}
};
} }
}, },
@ -159,23 +141,75 @@ class SortedDocValuesWriter extends DocValuesWriter {
new Iterable<Number>() { new Iterable<Number>() {
@Override @Override
public Iterator<Number> iterator() { public Iterator<Number> iterator() {
return new Iterator<Number>() { return new OrdsIterator(ordMap, bufferedDocCount, maxDoc, emptyOrd);
}
});
}
@Override
public void abort() {
}
// iterates over the unique values we have in ram
private class ValuesIterator implements Iterator<BytesRef> {
final int sortedValues[];
final BytesRef scratch = new BytesRef();
final int valueCount;
int ordUpto;
ValuesIterator(int sortedValues[], int valueCount) {
this.sortedValues = sortedValues;
this.valueCount = valueCount;
}
@Override
public boolean hasNext() {
return ordUpto < valueCount;
}
@Override
public BytesRef next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
hash.get(sortedValues[ordUpto], scratch);
ordUpto++;
return scratch;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
// iterates over the ords for each doc we have in ram
private class OrdsIterator implements Iterator<Number> {
final int ordMap[];
final int size;
final int maxDoc;
final int emptyOrd; // nocommit
int docUpto; int docUpto;
OrdsIterator(int ordMap[], int size, int maxDoc, int emptyOrd) {
this.ordMap = ordMap;
this.size = size;
this.maxDoc = maxDoc;
this.emptyOrd = emptyOrd;
}
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return docUpto < maxDoc; return docUpto < maxDoc;
} }
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override @Override
public Number next() { public Number next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
int ord; int ord;
if (docUpto < bufferedDocCount) { if (docUpto < size) {
ord = pending[docUpto]; ord = pending[docUpto];
} else { } else {
ord = emptyOrd; ord = emptyOrd;
@ -184,12 +218,10 @@ class SortedDocValuesWriter extends DocValuesWriter {
// TODO: make reusable Number // TODO: make reusable Number
return ordMap[ord]; return ordMap[ord];
} }
};
}
});
}
@Override @Override
public void abort() { public void remove() {
throw new UnsupportedOperationException();
}
} }
} }

View File

@ -18,6 +18,8 @@ package org.apache.lucene.codecs.asserting;
*/ */
import java.io.IOException; import java.io.IOException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.apache.lucene.codecs.DocValuesConsumer; import org.apache.lucene.codecs.DocValuesConsumer;
import org.apache.lucene.codecs.DocValuesFormat; import org.apache.lucene.codecs.DocValuesFormat;
@ -75,6 +77,7 @@ public class AssertingDocValuesFormat extends DocValuesFormat {
count++; count++;
} }
assert count == maxDoc; assert count == maxDoc;
checkIterator(values.iterator(), maxDoc);
in.addNumericField(field, values); in.addNumericField(field, values);
} }
@ -87,6 +90,7 @@ public class AssertingDocValuesFormat extends DocValuesFormat {
count++; count++;
} }
assert count == maxDoc; assert count == maxDoc;
checkIterator(values.iterator(), maxDoc);
in.addBinaryField(field, values); in.addBinaryField(field, values);
} }
@ -118,9 +122,33 @@ public class AssertingDocValuesFormat extends DocValuesFormat {
assert count == maxDoc; assert count == maxDoc;
assert seenOrds.cardinality() == valueCount; assert seenOrds.cardinality() == valueCount;
checkIterator(values.iterator(), valueCount);
checkIterator(docToOrd.iterator(), maxDoc);
in.addSortedField(field, values, docToOrd); in.addSortedField(field, values, docToOrd);
} }
private <T> void checkIterator(Iterator<T> iterator, int expectedSize) {
for (int i = 0; i < expectedSize; i++) {
boolean hasNext = iterator.hasNext();
assert hasNext;
T v = iterator.next();
assert v != null;
try {
iterator.remove();
throw new AssertionError("broken iterator (supports remove): " + iterator);
} catch (UnsupportedOperationException expected) {
// ok
}
}
assert !iterator.hasNext();
try {
iterator.next();
throw new AssertionError("broken iterator (allows next() when hasNext==false) " + iterator);
} catch (NoSuchElementException expected) {
// ok
}
}
@Override @Override
public void close() throws IOException { public void close() throws IOException {
in.close(); in.close();