diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/data/IntegerVector.java')
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/data/IntegerVector.java | 253 |
1 files changed, 189 insertions, 64 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/data/IntegerVector.java b/src/de/lmu/ifi/dbs/elki/data/IntegerVector.java index ae0d8cce..595fcd94 100644 --- a/src/de/lmu/ifi/dbs/elki/data/IntegerVector.java +++ b/src/de/lmu/ifi/dbs/elki/data/IntegerVector.java @@ -38,25 +38,42 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; * * @author Erich Schubert */ -public class IntegerVector extends AbstractNumberVector<IntegerVector, Integer> implements ByteBufferSerializer<IntegerVector> { +public class IntegerVector extends AbstractNumberVector<Integer> { /** - * Static instance (object factory) + * Static instance (object factory). */ - public static final IntegerVector STATIC = new IntegerVector(new int[0], true); + public static final IntegerVector.Factory STATIC = new IntegerVector.Factory(); /** - * Keeps the values of the real vector + * Serializer for up to 127 dimensions. */ - private int[] values; + public static final ByteBufferSerializer<IntegerVector> BYTE_SERIALIZER = new SmallSerializer(); + + /** + * Serializer for up to 2^15-1 dimensions. + */ + public static final ByteBufferSerializer<IntegerVector> SHORT_SERIALIZER = new ShortSerializer(); + + /** + * Serializer using varint encoding. + */ + public static final ByteBufferSerializer<IntegerVector> VARIABLE_SERIALIZER = new VariableSerializer(); + + /** + * Keeps the values of the real vector. + */ + private final int[] values; /** * Private constructor. NOT for public use. + * + * @param values Value data + * @param nocopy Flag to use without copying. */ private IntegerVector(int[] values, boolean nocopy) { - if(nocopy) { + if (nocopy) { this.values = values; - } - else { + } else { this.values = new int[values.length]; System.arraycopy(values, 0, this.values, 0, values.length); } @@ -85,13 +102,15 @@ public class IntegerVector extends AbstractNumberVector<IntegerVector, Integer> * * @throws IllegalArgumentException if the specified dimension is out of range * of the possible attributes + * + * {@inheritDoc} */ @Override + @Deprecated public Integer getValue(int dimension) { try { - return values[dimension - 1]; - } - catch(IndexOutOfBoundsException e) { + return Integer.valueOf(values[dimension - 1]); + } catch (IndexOutOfBoundsException e) { throw new IllegalArgumentException("Dimension " + dimension + " out of range."); } } @@ -104,13 +123,14 @@ public class IntegerVector extends AbstractNumberVector<IntegerVector, Integer> * * @throws IllegalArgumentException if the specified dimension is out of range * of the possible attributes + * + * {@inheritDoc} */ @Override public double doubleValue(int dimension) { try { return values[dimension - 1]; - } - catch(IndexOutOfBoundsException e) { + } catch (IndexOutOfBoundsException e) { throw new IllegalArgumentException("Dimension " + dimension + " out of range."); } } @@ -123,13 +143,14 @@ public class IntegerVector extends AbstractNumberVector<IntegerVector, Integer> * * @throws IllegalArgumentException if the specified dimension is out of range * of the possible attributes + * + * {@inheritDoc} */ @Override public long longValue(int dimension) { try { return values[dimension - 1]; - } - catch(IndexOutOfBoundsException e) { + } catch (IndexOutOfBoundsException e) { throw new IllegalArgumentException("Dimension " + dimension + " out of range."); } } @@ -148,7 +169,7 @@ public class IntegerVector extends AbstractNumberVector<IntegerVector, Integer> @Override public Vector getColumnVector() { double[] data = new double[values.length]; - for(int i = 0; i < values.length; i++) { + for (int i = 0; i < values.length; i++) { data[i] = values[i]; } return new Vector(data); @@ -156,76 +177,180 @@ public class IntegerVector extends AbstractNumberVector<IntegerVector, Integer> @Override public String toString() { - StringBuffer featureLine = new StringBuffer(); - for(int i = 0; i < values.length; i++) { + StringBuilder featureLine = new StringBuilder(); + for (int i = 0; i < values.length; i++) { featureLine.append(values[i]); - if(i + 1 < values.length) { + if (i + 1 < values.length) { featureLine.append(ATTRIBUTE_SEPARATOR); } } return featureLine.toString(); } - @Override - public <A> IntegerVector newFeatureVector(A array, ArrayAdapter<Integer, A> adapter) { - int dim = adapter.size(array); - int[] values = new int[dim]; - for(int i = 0; i < dim; i++) { - values[i] = adapter.get(array, i); + /** + * Factory for integer vectors. + * + * @author Erich Schubert + * + * @apiviz.has IntegerVector + */ + public static class Factory extends AbstractNumberVector.Factory<IntegerVector, Integer> { + @Override + public <A> IntegerVector newFeatureVector(A array, ArrayAdapter<Integer, A> adapter) { + int dim = adapter.size(array); + int[] values = new int[dim]; + for (int i = 0; i < dim; i++) { + values[i] = adapter.get(array, i); + } + return new IntegerVector(values, true); } - return new IntegerVector(values, true); - } - @Override - public <A> IntegerVector newNumberVector(A array, NumberArrayAdapter<?, A> adapter) { - int dim = adapter.size(array); - int[] values = new int[dim]; - for(int i = 0; i < dim; i++) { - values[i] = adapter.getInteger(array, i); + @Override + public <A> IntegerVector newNumberVector(A array, NumberArrayAdapter<?, ? super A> adapter) { + int dim = adapter.size(array); + int[] values = new int[dim]; + for (int i = 0; i < dim; i++) { + values[i] = adapter.getInteger(array, i); + } + return new IntegerVector(values, true); } - return new IntegerVector(values, true); - } - @Override - public IntegerVector fromByteBuffer(ByteBuffer buffer) throws IOException { - final short dimensionality = buffer.getShort(); - final int len = ByteArrayUtil.SIZE_SHORT + ByteArrayUtil.SIZE_DOUBLE * dimensionality; - if(buffer.remaining() < len) { - throw new IOException("Not enough data for a double vector!"); - } - int[] values = new int[dimensionality]; - buffer.asIntBuffer().get(values); - return new IntegerVector(values, false); - } + @Override + public ByteBufferSerializer<IntegerVector> getDefaultSerializer() { + return VARIABLE_SERIALIZER; + } + + @Override + public Class<? super IntegerVector> getRestrictionClass() { + return IntegerVector.class; + } - @Override - public void toByteBuffer(ByteBuffer buffer, IntegerVector vec) throws IOException { - final short dimensionality = buffer.getShort(); - final int len = ByteArrayUtil.SIZE_SHORT + ByteArrayUtil.SIZE_DOUBLE * dimensionality; - if(buffer.remaining() < len) { - throw new IOException("Not enough space for the double vector!"); - } - buffer.putShort(dimensionality); - buffer.asIntBuffer().put(vec.values); + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + @Override + protected IntegerVector.Factory makeInstance() { + return STATIC; + } + } } - @Override - public int getByteSize(IntegerVector vec) { - return ByteArrayUtil.SIZE_SHORT + ByteArrayUtil.SIZE_DOUBLE * vec.getDimensionality(); + /** + * Serialization class for dense integer vectors with up to 127 dimensions, by + * using a byte for storing the dimensionality. + * + * @author Erich Schubert + * + * @apiviz.uses IntegerVector - - «serializes» + */ + public static class SmallSerializer implements ByteBufferSerializer<IntegerVector> { + @Override + public IntegerVector fromByteBuffer(ByteBuffer buffer) throws IOException { + final byte dimensionality = buffer.get(); + assert (buffer.remaining() >= ByteArrayUtil.SIZE_INT * dimensionality); + final int[] values = new int[dimensionality]; + for (int i = 0; i < dimensionality; i++) { + values[i] = buffer.getInt(); + } + return new IntegerVector(values, true); + } + + @Override + public void toByteBuffer(ByteBuffer buffer, IntegerVector vec) throws IOException { + assert (vec.values.length < Byte.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Byte.MAX_VALUE + "!"; + assert (buffer.remaining() >= ByteArrayUtil.SIZE_INT * vec.values.length); + buffer.put((byte) vec.values.length); + for (int i = 0; i < vec.values.length; i++) { + buffer.putInt(vec.values[i]); + } + } + + @Override + public int getByteSize(IntegerVector vec) { + assert (vec.values.length < Byte.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Byte.MAX_VALUE + "!"; + return ByteArrayUtil.SIZE_BYTE + ByteArrayUtil.SIZE_INT * vec.getDimensionality(); + } } + /** + * Serialization class for dense integer vectors with up to + * {@link Short#MAX_VALUE} dimensions, by using a short for storing the + * dimensionality. + * + * @author Erich Schubert + * + * @apiviz.uses IntegerVector - - «serializes» + */ + public static class ShortSerializer implements ByteBufferSerializer<IntegerVector> { + @Override + public IntegerVector fromByteBuffer(ByteBuffer buffer) throws IOException { + final short dimensionality = buffer.getShort(); + assert (buffer.remaining() >= ByteArrayUtil.SIZE_INT * dimensionality); + final int[] values = new int[dimensionality]; + for (int i = 0; i < dimensionality; i++) { + values[i] = buffer.getInt(); + } + return new IntegerVector(values, true); + } + + @Override + public void toByteBuffer(ByteBuffer buffer, IntegerVector vec) throws IOException { + assert (vec.values.length < Short.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Short.MAX_VALUE + "!"; + assert (buffer.remaining() >= ByteArrayUtil.SIZE_INT * vec.values.length); + buffer.putShort((short) vec.values.length); + for (int i = 0; i < vec.values.length; i++) { + buffer.putInt(vec.values[i]); + } + } + + @Override + public int getByteSize(IntegerVector vec) { + assert (vec.values.length < Short.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Short.MAX_VALUE + "!"; + return ByteArrayUtil.SIZE_SHORT + ByteArrayUtil.SIZE_INT * vec.getDimensionality(); + } + } /** - * Parameterization class + * Serialization class for variable dimensionality by using VarInt encoding. * * @author Erich Schubert * - * @apiviz.exclude + * @apiviz.uses IntegerVector - - «serializes» */ - public static class Parameterizer extends AbstractParameterizer { + public static class VariableSerializer implements ByteBufferSerializer<IntegerVector> { + @Override + public IntegerVector fromByteBuffer(ByteBuffer buffer) throws IOException { + final int dimensionality = ByteArrayUtil.readUnsignedVarint(buffer); + assert (buffer.remaining() >= ByteArrayUtil.SIZE_INT * dimensionality); + final int[] values = new int[dimensionality]; + for (int i = 0; i < dimensionality; i++) { + values[i] = ByteArrayUtil.readSignedVarint(buffer); + } + return new IntegerVector(values, true); + } + @Override - protected IntegerVector makeInstance() { - return STATIC; + public void toByteBuffer(ByteBuffer buffer, IntegerVector vec) throws IOException { + assert (vec.values.length < Short.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Short.MAX_VALUE + "!"; + ByteArrayUtil.writeUnsignedVarint(buffer, vec.values.length); + for (int i = 0; i < vec.values.length; i++) { + ByteArrayUtil.writeSignedVarint(buffer, vec.values[i]); + } + } + + @Override + public int getByteSize(IntegerVector vec) { + assert (vec.values.length < Short.MAX_VALUE) : "This serializer only supports a maximum dimensionality of " + Short.MAX_VALUE + "!"; + int len = ByteArrayUtil.getUnsignedVarintSize(vec.values.length); + for (int i = 0; i < vec.values.length; i++) { + len += ByteArrayUtil.getSignedVarintSize(vec.values[i]); + } + return len; } } -}
\ No newline at end of file +} |