mirror of https://github.com/apache/lucene.git
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
This commit is contained in:
parent
bc23b9f4d3
commit
0e731a4b64
|
@ -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<? extends Attribute> 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 <code>precisionStep</code>
|
||||
* {@link NumericUtils#PRECISION_STEP_DEFAULT} (4). The stream is not yet initialized,
|
||||
* before using set a value using the various set<em>???</em>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<em>???</em>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 {
|
|||
* <code>new Field(name, new NumericTokenStream(precisionStep).setLongValue(value))</code>
|
||||
*/
|
||||
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 {
|
|||
* <code>new Field(name, new NumericTokenStream(precisionStep).setIntValue(value))</code>
|
||||
*/
|
||||
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 {
|
|||
* <code>new Field(name, new NumericTokenStream(precisionStep).setDoubleValue(value))</code>
|
||||
*/
|
||||
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 {
|
|||
* <code>new Field(name, new NumericTokenStream(precisionStep).setFloatValue(value))</code>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue