/** * Gets an off-heap compact representation of the sketch using the given memory * @param dstMem memory for the compact sketch (can be null) * @return compact sketch (off-heap if memory is provided) */ public ArrayOfDoublesCompactSketch compact(final WritableMemory dstMem) { if (dstMem == null) { return new HeapArrayOfDoublesCompactSketch(this); } return new DirectArrayOfDoublesCompactSketch(this, dstMem); }
@Override public ArrayOfDoublesSketchIterator iterator() { return new DirectArrayOfDoublesSketchIterator( mem_, ENTRIES_START, getRetainedEntries(), numValues_); }
DirectArrayOfDoublesCompactSketch(final long[] keys, final double[] values, final long theta, final boolean isEmpty, final int numValues, final short seedHash, final WritableMemory dstMem) { super(numValues); checkIfEnoughMemory(dstMem, values.length, numValues); mem_ = dstMem; dstMem.putByte(PREAMBLE_LONGS_BYTE, (byte) 1); dstMem.putByte(SERIAL_VERSION_BYTE, serialVersionUID); dstMem.putByte(FAMILY_ID_BYTE, (byte) Family.TUPLE.getID()); dstMem.putByte(SKETCH_TYPE_BYTE, (byte) SerializerDeserializer.SketchType.ArrayOfDoublesCompactSketch.ordinal()); final boolean isBigEndian = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN); isEmpty_ = isEmpty; final int count = keys.length; dstMem.putByte(FLAGS_BYTE, (byte) ( (isBigEndian ? 1 << Flags.IS_BIG_ENDIAN.ordinal() : 0) | (isEmpty_ ? 1 << Flags.IS_EMPTY.ordinal() : 0) | (count > 0 ? 1 << Flags.HAS_ENTRIES.ordinal() : 0) )); dstMem.putByte(NUM_VALUES_BYTE, (byte) numValues_); dstMem.putShort(SEED_HASH_SHORT, seedHash); theta_ = theta; dstMem.putLong(THETA_LONG, theta_); if (count > 0) { dstMem.putInt(RETAINED_ENTRIES_INT, count); dstMem.putLongArray(ENTRIES_START, keys, 0, count); dstMem.putDoubleArray( ENTRIES_START + ((long) SIZE_OF_KEY_BYTES * count), values, 0, values.length); } }
final long theta, final WritableMemory dstMem) { super(sketch.getNumValues()); checkIfEnoughMemory(dstMem, sketch.getRetainedEntries(), sketch.getNumValues()); mem_ = dstMem; dstMem.putByte(PREAMBLE_LONGS_BYTE, (byte) 1);
@Override public ArrayOfDoublesCompactSketch getResult(final WritableMemory mem) { if (mem == null || count_ == 0) { return getResult(); } final ArrayOfDoublesCompactSketch result = new DirectArrayOfDoublesCompactSketch( Arrays.copyOfRange(keys_, 0, count_), Arrays.copyOfRange(values_, 0, count_ * numValues_), theta_, isEmpty_, numValues_, seedHash_, mem ); reset(); return result; }
@Override public double[][] getValues() { final int count = getRetainedEntries(); final double[][] values = new double[count][]; if (count > 0) { int valuesOffset = ENTRIES_START + (SIZE_OF_KEY_BYTES * count); for (int i = 0; i < count; i++) { final double[] array = new double[numValues_]; mem_.getDoubleArray(valuesOffset, array, 0, numValues_); values[i] = array; valuesOffset += SIZE_OF_VALUE_BYTES * numValues_; } } return values; }
DirectArrayOfDoublesCompactSketch(final long[] keys, final double[] values, final long theta, final boolean isEmpty, final int numValues, final short seedHash, final WritableMemory dstMem) { super(numValues); checkIfEnoughMemory(dstMem, values.length, numValues); mem_ = dstMem; dstMem.putByte(PREAMBLE_LONGS_BYTE, (byte) 1); dstMem.putByte(SERIAL_VERSION_BYTE, serialVersionUID); dstMem.putByte(FAMILY_ID_BYTE, (byte) Family.TUPLE.getID()); dstMem.putByte(SKETCH_TYPE_BYTE, (byte) SerializerDeserializer.SketchType.ArrayOfDoublesCompactSketch.ordinal()); final boolean isBigEndian = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN); isEmpty_ = isEmpty; final int count = keys.length; dstMem.putByte(FLAGS_BYTE, (byte) ( (isBigEndian ? 1 << Flags.IS_BIG_ENDIAN.ordinal() : 0) | (isEmpty_ ? 1 << Flags.IS_EMPTY.ordinal() : 0) | (count > 0 ? 1 << Flags.HAS_ENTRIES.ordinal() : 0) )); dstMem.putByte(NUM_VALUES_BYTE, (byte) numValues_); dstMem.putShort(SEED_HASH_SHORT, seedHash); theta_ = theta; dstMem.putLong(THETA_LONG, theta_); if (count > 0) { dstMem.putInt(RETAINED_ENTRIES_INT, count); dstMem.putLongArray(ENTRIES_START, keys, 0, count); dstMem.putDoubleArray(ENTRIES_START + SIZE_OF_KEY_BYTES * count, values, 0, values.length); } }
/** * Wrap the given Memory and seed as a ArrayOfDoublesSketch * @param mem the given Memory * @param seed the given seed * @return an ArrayOfDoublesSketch */ public static ArrayOfDoublesSketch wrap(final Memory mem, final long seed) { final SerializerDeserializer.SketchType sketchType = SerializerDeserializer.getSketchType(mem); if (sketchType == SerializerDeserializer.SketchType.ArrayOfDoublesQuickSelectSketch) { return new DirectArrayOfDoublesQuickSelectSketchR(mem, seed); } return new DirectArrayOfDoublesCompactSketch(mem, seed); }
@Override public byte[] toByteArray() { final int count = getRetainedEntries(); int sizeBytes = EMPTY_SIZE; if (count > 0) { sizeBytes = ENTRIES_START + (SIZE_OF_KEY_BYTES * count) + (SIZE_OF_VALUE_BYTES * count * numValues_); } final byte[] byteArray = new byte[sizeBytes]; final WritableMemory mem = WritableMemory.wrap(byteArray); mem_.copyTo(0, mem, 0, sizeBytes); return byteArray; }
final long theta, final WritableMemory dstMem) { super(sketch.getNumValues()); checkIfEnoughMemory(dstMem, sketch.getRetainedEntries(), sketch.getNumValues()); mem_ = dstMem; dstMem.putByte(PREAMBLE_LONGS_BYTE, (byte) 1);
/** * Returns the resulting union in the form of a compact sketch * @param dstMem memory for the result (can be null) * @return compact sketch representing the union (off-heap if memory is provided) */ public ArrayOfDoublesCompactSketch getResult(final WritableMemory dstMem) { if (sketch_.getRetainedEntries() > sketch_.getNominalEntries()) { theta_ = Math.min(theta_, sketch_.getNewTheta()); } if (dstMem == null) { return new HeapArrayOfDoublesCompactSketch(sketch_, theta_); } return new DirectArrayOfDoublesCompactSketch(sketch_, theta_, dstMem); }
@Override public ArrayOfDoublesSketchIterator iterator() { return new DirectArrayOfDoublesSketchIterator( mem_, ENTRIES_START, getRetainedEntries(), numValues_); }
@Test public void heapToDirectExactTwoDoubles() { ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder().setNumberOfValues(2).build(); sketch1.update("a", new double[] {1, 2}); sketch1.update("b", new double[] {1, 2}); sketch1.update("c", new double[] {1, 2}); sketch1.update("d", new double[] {1, 2}); sketch1.update("a", new double[] {1, 2}); sketch1.update("b", new double[] {1, 2}); sketch1.update("c", new double[] {1, 2}); sketch1.update("d", new double[] {1, 2}); ArrayOfDoublesSketch sketch2 = new DirectArrayOfDoublesCompactSketch(Memory.wrap(sketch1.compact().toByteArray())); Assert.assertFalse(sketch2.isEmpty()); Assert.assertFalse(sketch2.isEstimationMode()); Assert.assertEquals(sketch2.getEstimate(), 4.0); Assert.assertEquals(sketch2.getUpperBound(1), 4.0); Assert.assertEquals(sketch2.getLowerBound(1), 4.0); Assert.assertEquals(sketch2.getThetaLong(), Long.MAX_VALUE); Assert.assertEquals(sketch2.getTheta(), 1.0); double[][] values = sketch2.getValues(); Assert.assertEquals(values.length, 4); for (double[] array: values) { Assert.assertEquals(array.length, 2); Assert.assertEquals(array[0], 2.0); Assert.assertEquals(array[1], 4.0); } }
@Override public double[][] getValues() { final int count = getRetainedEntries(); final double[][] values = new double[count][]; if (count > 0) { int valuesOffset = ENTRIES_START + SIZE_OF_KEY_BYTES * count; for (int i = 0; i < count; i++) { final double[] array = new double[numValues_]; mem_.getDoubleArray(valuesOffset, array, 0, numValues_); values[i] = array; valuesOffset += SIZE_OF_VALUE_BYTES * numValues_; } } return values; }
/** * Gets an off-heap compact representation of the sketch using the given memory * @param dstMem memory for the compact sketch (can be null) * @return compact sketch (off-heap if memory is provided) */ public ArrayOfDoublesCompactSketch compact(final WritableMemory dstMem) { if (dstMem == null) { return new HeapArrayOfDoublesCompactSketch(this); } return new DirectArrayOfDoublesCompactSketch(this, dstMem); }
@Override public byte[] toByteArray() { final int count = getRetainedEntries(); int sizeBytes = EMPTY_SIZE; if (count > 0) { sizeBytes = ENTRIES_START + SIZE_OF_KEY_BYTES * count + SIZE_OF_VALUE_BYTES * count * numValues_; } final byte[] byteArray = new byte[sizeBytes]; final WritableMemory mem = WritableMemory.wrap(byteArray); mem_.copyTo(0, mem, 0, sizeBytes); return byteArray; }
@Override public ArrayOfDoublesCompactSketch getResult(final WritableMemory mem) { if (mem == null || count_ == 0) { return getResult(); } final ArrayOfDoublesCompactSketch result = new DirectArrayOfDoublesCompactSketch( Arrays.copyOfRange(keys_, 0, count_), Arrays.copyOfRange(values_, 0, count_ * numValues_), theta_, isEmpty_, numValues_, seedHash_, mem ); reset(); return result; }
/** * Wrap the given Memory and seed as a ArrayOfDoublesSketch * @param mem the given Memory * @param seed the given seed * @return an ArrayOfDoublesSketch */ public static ArrayOfDoublesSketch wrap(final Memory mem, final long seed) { final SerializerDeserializer.SketchType sketchType = SerializerDeserializer.getSketchType(mem); if (sketchType == SerializerDeserializer.SketchType.ArrayOfDoublesQuickSelectSketch) { return new DirectArrayOfDoublesQuickSelectSketchR(mem, seed); } return new DirectArrayOfDoublesCompactSketch(mem, seed); }
/** * Returns the resulting union in the form of a compact sketch * @param dstMem memory for the result (can be null) * @return compact sketch representing the union (off-heap if memory is provided) */ public ArrayOfDoublesCompactSketch getResult(final WritableMemory dstMem) { if (sketch_.getRetainedEntries() > sketch_.getNominalEntries()) { theta_ = Math.min(theta_, sketch_.getNewTheta()); } if (dstMem == null) { return new HeapArrayOfDoublesCompactSketch(sketch_, theta_); } return new DirectArrayOfDoublesCompactSketch(sketch_, theta_, dstMem); }