summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/data/IntegerVector.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/data/IntegerVector.java')
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/IntegerVector.java253
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
+}