LUCENE-5611: fix the crazy getAttribute API to prevent double lookups and extra code everywhere

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/branches/lucene5611@1590731 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2014-04-28 18:13:15 +00:00
parent 67ebc26fa9
commit f0414ff3af
11 changed files with 40 additions and 56 deletions

View File

@ -171,8 +171,9 @@ public abstract class TokenStream extends AttributeSource implements Closeable {
*/
public void end() throws IOException {
clearAttributes(); // LUCENE-3849: don't consume dirty atts
if (hasAttribute(PositionIncrementAttribute.class)) {
getAttribute(PositionIncrementAttribute.class).setPositionIncrement(0);
PositionIncrementAttribute posIncAtt = getAttribute(PositionIncrementAttribute.class);
if (posIncAtt != null) {
posIncAtt.setPositionIncrement(0);
}
}

View File

@ -547,18 +547,10 @@ final class DefaultIndexingChain extends DocConsumer {
if (invertState.attributeSource != stream) {
// EmptyTokenStream gets angry otherwise:
if (stream.hasAttribute(TermToBytesRefAttribute.class)) {
invertState.termAttribute = stream.getAttribute(TermToBytesRefAttribute.class);
} else {
invertState.termAttribute = null;
}
invertState.termAttribute = stream.getAttribute(TermToBytesRefAttribute.class);
invertState.posIncrAttribute = stream.addAttribute(PositionIncrementAttribute.class);
invertState.offsetAttribute = stream.addAttribute(OffsetAttribute.class);
if (stream.hasAttribute(PayloadAttribute.class)) {
invertState.payloadAttribute = stream.getAttribute(PayloadAttribute.class);
} else {
invertState.payloadAttribute = null;
}
invertState.payloadAttribute = stream.getAttribute(PayloadAttribute.class);
invertState.attributeSource = stream;
}

View File

@ -287,22 +287,20 @@ public class AttributeSource {
}
/**
* The caller must pass in a Class<? extends Attribute> value.
* Returns the instance of the passed in Attribute contained in this AttributeSource
* <p>
* The caller must pass in a Class&lt;? extends Attribute&gt; value.
*
* @throws IllegalArgumentException if this AttributeSource does not contain the
* Attribute. It is recommended to always use {@link #addAttribute} even in consumers
* of TokenStreams, because you cannot know if a specific TokenStream really uses
* a specific Attribute. {@link #addAttribute} will automatically make the attribute
* available. If you want to only use the attribute, if it is available (to optimize
* consuming), use {@link #hasAttribute}.
* @returns instance of the passed in Attribute, or {@code null} if this AttributeSource
* does not contain the Attribute. It is recommended to always use
* {@link #addAttribute} even in consumers of TokenStreams, because you cannot
* know if a specific TokenStream really uses a specific Attribute.
* {@link #addAttribute} will automatically make the attribute available.
* If you want to only use the attribute, if it is available (to optimize
* consuming), use {@link #hasAttribute}.
*/
public final <T extends Attribute> T getAttribute(Class<T> attClass) {
AttributeImpl attImpl = attributes.get(attClass);
if (attImpl == null) {
throw new IllegalArgumentException("This AttributeSource does not have the attribute '" + attClass.getName() + "'.");
}
return attClass.cast(attImpl);
return attClass.cast(attributes.get(attClass));
}
private State getCurrentState() {

View File

@ -207,12 +207,8 @@ public class QueryBuilder {
buffer = new CachingTokenFilter(source);
buffer.reset();
if (buffer.hasAttribute(TermToBytesRefAttribute.class)) {
termAtt = buffer.getAttribute(TermToBytesRefAttribute.class);
}
if (buffer.hasAttribute(PositionIncrementAttribute.class)) {
posIncrAtt = buffer.getAttribute(PositionIncrementAttribute.class);
}
termAtt = buffer.getAttribute(TermToBytesRefAttribute.class);
posIncrAtt = buffer.getAttribute(PositionIncrementAttribute.class);
if (termAtt != null) {
try {

View File

@ -31,10 +31,12 @@ public class TestNumericTokenStream extends BaseTokenStreamTestCase {
public void testLongStream() throws Exception {
final NumericTokenStream stream=new NumericTokenStream().setLongValue(lvalue);
// use getAttribute to test if attributes really exist, if not an IAE will be throwed
final TermToBytesRefAttribute bytesAtt = stream.getAttribute(TermToBytesRefAttribute.class);
assertNotNull(bytesAtt);
final TypeAttribute typeAtt = stream.getAttribute(TypeAttribute.class);
assertNotNull(typeAtt);
final NumericTokenStream.NumericTermAttribute numericAtt = stream.getAttribute(NumericTokenStream.NumericTermAttribute.class);
assertNotNull(numericAtt);
final BytesRef bytes = bytesAtt.getBytesRef();
stream.reset();
assertEquals(64, numericAtt.getValueSize());
@ -53,10 +55,12 @@ public class TestNumericTokenStream extends BaseTokenStreamTestCase {
public void testIntStream() throws Exception {
final NumericTokenStream stream=new NumericTokenStream().setIntValue(ivalue);
// use getAttribute to test if attributes really exist, if not an IAE will be throwed
final TermToBytesRefAttribute bytesAtt = stream.getAttribute(TermToBytesRefAttribute.class);
assertNotNull(bytesAtt);
final TypeAttribute typeAtt = stream.getAttribute(TypeAttribute.class);
assertNotNull(typeAtt);
final NumericTokenStream.NumericTermAttribute numericAtt = stream.getAttribute(NumericTokenStream.NumericTermAttribute.class);
assertNotNull(numericAtt);
final BytesRef bytes = bytesAtt.getBytesRef();
stream.reset();
assertEquals(32, numericAtt.getValueSize());

View File

@ -639,8 +639,8 @@ public class TestStressIndexing2 extends LuceneTestCase {
int freq1 = dpEnum1.freq();
int freq2 = dpEnum2.freq();
assertEquals(freq1, freq2);
OffsetAttribute offsetAtt1 = dpEnum1.attributes().hasAttribute(OffsetAttribute.class) ? dpEnum1.attributes().getAttribute(OffsetAttribute.class) : null;
OffsetAttribute offsetAtt2 = dpEnum2.attributes().hasAttribute(OffsetAttribute.class) ? dpEnum2.attributes().getAttribute(OffsetAttribute.class) : null;
OffsetAttribute offsetAtt1 = dpEnum1.attributes().getAttribute(OffsetAttribute.class);
OffsetAttribute offsetAtt2 = dpEnum2.attributes().getAttribute(OffsetAttribute.class);
if (offsetAtt1 != null) {
assertNotNull(offsetAtt2);

View File

@ -90,7 +90,9 @@ public class TestAttributeSource extends LuceneTestCase {
assertFalse("No more attributes", it.hasNext());
final FlagsAttribute flagsAtt2 = clone.getAttribute(FlagsAttribute.class);
assertNotNull(flagsAtt2);
final TypeAttribute typeAtt2 = clone.getAttribute(TypeAttribute.class);
assertNotNull(typeAtt2);
assertNotSame("FlagsAttribute of original and clone must be different instances", flagsAtt2, flagsAtt);
assertNotSame("TypeAttribute of original and clone must be different instances", typeAtt2, typeAtt);
assertEquals("FlagsAttribute of original and clone must be equal", flagsAtt2, flagsAtt);

View File

@ -685,11 +685,11 @@ public abstract class BaseTokenStreamTestCase extends LuceneTestCase {
int remainder = random.nextInt(10);
Reader reader = new StringReader(text);
TokenStream ts = a.tokenStream("dummy", useCharFilter ? new MockCharFilter(reader, remainder) : reader);
CharTermAttribute termAtt = ts.hasAttribute(CharTermAttribute.class) ? ts.getAttribute(CharTermAttribute.class) : null;
OffsetAttribute offsetAtt = ts.hasAttribute(OffsetAttribute.class) ? ts.getAttribute(OffsetAttribute.class) : null;
PositionIncrementAttribute posIncAtt = ts.hasAttribute(PositionIncrementAttribute.class) ? ts.getAttribute(PositionIncrementAttribute.class) : null;
PositionLengthAttribute posLengthAtt = ts.hasAttribute(PositionLengthAttribute.class) ? ts.getAttribute(PositionLengthAttribute.class) : null;
TypeAttribute typeAtt = ts.hasAttribute(TypeAttribute.class) ? ts.getAttribute(TypeAttribute.class) : null;
CharTermAttribute termAtt = ts.getAttribute(CharTermAttribute.class);
OffsetAttribute offsetAtt = ts.getAttribute(OffsetAttribute.class);
PositionIncrementAttribute posIncAtt = ts.getAttribute(PositionIncrementAttribute.class);
PositionLengthAttribute posLengthAtt = ts.getAttribute(PositionLengthAttribute.class);
TypeAttribute typeAtt = ts.getAttribute(TypeAttribute.class);
List<String> tokens = new ArrayList<>();
List<String> types = new ArrayList<>();
List<Integer> positions = new ArrayList<>();

View File

@ -47,23 +47,14 @@ public final class ValidatingTokenFilter extends TokenFilter {
private final Map<Integer,Integer> posToStartOffset = new HashMap<>();
private final Map<Integer,Integer> posToEndOffset = new HashMap<>();
private final PositionIncrementAttribute posIncAtt = getAttrIfExists(PositionIncrementAttribute.class);
private final PositionLengthAttribute posLenAtt = getAttrIfExists(PositionLengthAttribute.class);
private final OffsetAttribute offsetAtt = getAttrIfExists(OffsetAttribute.class);
private final CharTermAttribute termAtt = getAttrIfExists(CharTermAttribute.class);
private final PositionIncrementAttribute posIncAtt = getAttribute(PositionIncrementAttribute.class);
private final PositionLengthAttribute posLenAtt = getAttribute(PositionLengthAttribute.class);
private final OffsetAttribute offsetAtt = getAttribute(OffsetAttribute.class);
private final CharTermAttribute termAtt = getAttribute(CharTermAttribute.class);
private final boolean offsetsAreCorrect;
private final String name;
// Returns null if the attr wasn't already added
private <A extends Attribute> A getAttrIfExists(Class<A> att) {
if (hasAttribute(att)) {
return getAttribute(att);
} else {
return null;
}
}
/** The name arg is used to identify this stage when
* throwing exceptions (useful if you have more than one
* instance in your chain). */

View File

@ -230,10 +230,10 @@ public class JsonPreAnalyzedParser implements PreAnalyzedParser {
Map<String,Object> tok = new TreeMap<>();
while (it.hasNext()) {
Class<? extends Attribute> cl = it.next();
if (!ts.hasAttribute(cl)) {
Attribute att = ts.getAttribute(cl);
if (att == null) {
continue;
}
Attribute att = ts.getAttribute(cl);
if (cl.isAssignableFrom(CharTermAttribute.class)) {
CharTermAttribute catt = (CharTermAttribute)att;
cTerm = new String(catt.buffer(), 0, catt.length());

View File

@ -482,10 +482,10 @@ public final class SimplePreAnalyzedParser implements PreAnalyzedParser {
String tTerm = null;
while (it.hasNext()) {
Class<? extends Attribute> cl = it.next();
if (!ts.hasAttribute(cl)) {
Attribute att = ts.getAttribute(cl);
if (att == null) {
continue;
}
Attribute att = ts.getAttribute(cl);
if (cl.isAssignableFrom(CharTermAttribute.class)) {
CharTermAttribute catt = (CharTermAttribute)att;
cTerm = escape(catt.buffer(), catt.length());