From 0e731a4b644a6f9aaee5c26aa0b2aeaab93c7494 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Wed, 19 Jan 2011 18:59:02 +0000 Subject: [PATCH] LUCENE-2875: Support cloning of NumericTermAttribute by refactoring NumericTokenStream git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1060900 13f79535-47bb-0310-9956-ffa450edef68 --- .../lucene/analysis/NumericTokenStream.java | 130 ++++++++---------- 1 file changed, 56 insertions(+), 74 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/analysis/NumericTokenStream.java b/lucene/src/java/org/apache/lucene/analysis/NumericTokenStream.java index bed4c06c1a6..baf17ce9816 100644 --- a/lucene/src/java/org/apache/lucene/analysis/NumericTokenStream.java +++ b/lucene/src/java/org/apache/lucene/analysis/NumericTokenStream.java @@ -106,11 +106,18 @@ public final class NumericTokenStream extends TokenStream { long getRawValue(); /** Returns value size in bits (32 for {@code float}, {@code int}; 64 for {@code double}, {@code long}) */ int getValueSize(); + + /** @lucene.internal Don't call this method! */ + void init(long rawValue, int valSize, int precisionStep); + /** @lucene.internal Don't call this method! */ + void setShift(int shift); + /** @lucene.internal Don't call this method! */ + int incShift(); } + // just a wrapper to prevent adding CTA private static final class NumericAttributeFactory extends AttributeFactory { private final AttributeFactory delegate; - private NumericTokenStream ts = null; NumericAttributeFactory(AttributeFactory delegate) { this.delegate = delegate; @@ -118,41 +125,48 @@ public final class NumericTokenStream extends TokenStream { @Override public AttributeImpl createAttributeInstance(Class attClass) { - if (attClass == NumericTermAttribute.class) - return new NumericTermAttributeImpl(ts); if (CharTermAttribute.class.isAssignableFrom(attClass)) throw new IllegalArgumentException("NumericTokenStream does not support CharTermAttribute."); return delegate.createAttributeInstance(attClass); } } - private static final class NumericTermAttributeImpl extends AttributeImpl implements NumericTermAttribute,TermToBytesRefAttribute { - private final NumericTokenStream ts; + public static final class NumericTermAttributeImpl extends AttributeImpl implements NumericTermAttribute,TermToBytesRefAttribute { + private long rawValue = 0L; + private int valueSize = 0, shift = 0, precisionStep = 0; - public NumericTermAttributeImpl(NumericTokenStream ts) { - this.ts = ts; - } - public int toBytesRef(BytesRef bytes) { try { - assert ts.valSize == 64 || ts.valSize == 32; - return (ts.valSize == 64) ? - NumericUtils.longToPrefixCoded(ts.value, ts.shift, bytes) : - NumericUtils.intToPrefixCoded((int) ts.value, ts.shift, bytes); + assert valueSize == 64 || valueSize == 32; + return (valueSize == 64) ? + NumericUtils.longToPrefixCoded(rawValue, shift, bytes) : + NumericUtils.intToPrefixCoded((int) rawValue, shift, bytes); } catch (IllegalArgumentException iae) { - // return empty token before first + // return empty token before first or after last bytes.length = 0; return 0; } } - public int getShift() { return ts.shift; } - public long getRawValue() { return ts.value; } - public int getValueSize() { return ts.valSize; } + public int getShift() { return shift; } + public void setShift(int shift) { this.shift = shift; } + public int incShift() { + return (shift += precisionStep); + } + + public long getRawValue() { return rawValue; } + public int getValueSize() { return valueSize; } + + public void init(long rawValue, int valueSize, int precisionStep) { + this.rawValue = rawValue; + this.valueSize = valueSize; + this.precisionStep = precisionStep; + } @Override public void clear() { - // this attribute has no contents to clear + // this attribute has no contents to clear! + // we keep it untouched as it's fully controlled by outer class. } @Override @@ -167,23 +181,19 @@ public final class NumericTokenStream extends TokenStream { @Override public void copyTo(AttributeImpl target) { - // this attribute has no contents to copy - } - - @Override - public Object clone() { - // cannot throw CloneNotSupportedException (checked) - throw new UnsupportedOperationException(); + final NumericTermAttribute a = (NumericTermAttribute) target; + a.init(rawValue, valueSize, precisionStep); + a.setShift(shift); } } - + /** * Creates a token stream for numeric values using the default precisionStep * {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). The stream is not yet initialized, * before using set a value using the various set???Value() methods. */ public NumericTokenStream() { - this(NumericUtils.PRECISION_STEP_DEFAULT); + this(AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY, NumericUtils.PRECISION_STEP_DEFAULT); } /** @@ -192,15 +202,7 @@ public final class NumericTokenStream extends TokenStream { * before using set a value using the various set???Value() methods. */ public NumericTokenStream(final int precisionStep) { - super(new NumericAttributeFactory(AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY)); - // we must do this after the super call :( - ((NumericAttributeFactory) getAttributeFactory()).ts = this; - addAttribute(NumericTermAttribute.class); - - this.precisionStep = precisionStep; - if (precisionStep < 1) - throw new IllegalArgumentException("precisionStep must be >=1"); - shift = -precisionStep; + this(AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY, precisionStep); } /** @@ -212,14 +214,10 @@ public final class NumericTokenStream extends TokenStream { */ public NumericTokenStream(AttributeFactory factory, final int precisionStep) { super(new NumericAttributeFactory(factory)); - // we must do this after the super call :( - ((NumericAttributeFactory) getAttributeFactory()).ts = this; - addAttribute(NumericTermAttribute.class); - - this.precisionStep = precisionStep; if (precisionStep < 1) throw new IllegalArgumentException("precisionStep must be >=1"); - shift = -precisionStep; + this.precisionStep = precisionStep; + numericAtt.setShift(-precisionStep); } /** @@ -229,9 +227,8 @@ public final class NumericTokenStream extends TokenStream { * new Field(name, new NumericTokenStream(precisionStep).setLongValue(value)) */ public NumericTokenStream setLongValue(final long value) { - this.value = value; - valSize = 64; - shift = -precisionStep; + numericAtt.init(value, valSize = 64, precisionStep); + numericAtt.setShift(-precisionStep); return this; } @@ -242,9 +239,8 @@ public final class NumericTokenStream extends TokenStream { * new Field(name, new NumericTokenStream(precisionStep).setIntValue(value)) */ public NumericTokenStream setIntValue(final int value) { - this.value = value; - valSize = 32; - shift = -precisionStep; + numericAtt.init(value, valSize = 32, precisionStep); + numericAtt.setShift(-precisionStep); return this; } @@ -255,9 +251,8 @@ public final class NumericTokenStream extends TokenStream { * new Field(name, new NumericTokenStream(precisionStep).setDoubleValue(value)) */ public NumericTokenStream setDoubleValue(final double value) { - this.value = NumericUtils.doubleToSortableLong(value); - valSize = 64; - shift = -precisionStep; + numericAtt.init(NumericUtils.doubleToSortableLong(value), valSize = 64, precisionStep); + numericAtt.setShift(-precisionStep); return this; } @@ -268,9 +263,8 @@ public final class NumericTokenStream extends TokenStream { * new Field(name, new NumericTokenStream(precisionStep).setFloatValue(value)) */ public NumericTokenStream setFloatValue(final float value) { - this.value = NumericUtils.floatToSortableInt(value); - valSize = 32; - shift = -precisionStep; + numericAtt.init(NumericUtils.floatToSortableInt(value), valSize = 32, precisionStep); + numericAtt.setShift(-precisionStep); return this; } @@ -278,40 +272,28 @@ public final class NumericTokenStream extends TokenStream { public void reset() { if (valSize == 0) throw new IllegalStateException("call set???Value() before usage"); - shift = -precisionStep; + numericAtt.setShift(-precisionStep); } @Override public boolean incrementToken() { if (valSize == 0) throw new IllegalStateException("call set???Value() before usage"); - shift += precisionStep; - if (shift >= valSize) { - // reset so the attribute still works after exhausted stream - shift -= precisionStep; - return false; - } - + + // this will only clear all other attributes in this TokenStream clearAttributes(); - // the TermToBytesRefAttribute is directly accessing shift & value. + + final int shift = numericAtt.incShift(); typeAtt.setType((shift == 0) ? TOKEN_TYPE_FULL_PREC : TOKEN_TYPE_LOWER_PREC); posIncrAtt.setPositionIncrement((shift == 0) ? 1 : 0); - return true; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("(numeric,valSize=").append(valSize); - sb.append(",precisionStep=").append(precisionStep).append(')'); - return sb.toString(); + return (shift < valSize); } // members + private final NumericTermAttribute numericAtt = addAttribute(NumericTermAttribute.class); private final TypeAttribute typeAtt = addAttribute(TypeAttribute.class); private final PositionIncrementAttribute posIncrAtt = addAttribute(PositionIncrementAttribute.class); - int shift, valSize = 0; // valSize==0 means not initialized + private int valSize = 0; // valSize==0 means not initialized private final int precisionStep; - - long value = 0L; }