Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions src/main/java/org/apache/datasketches/common/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -175,22 +175,33 @@ public static byte[] longToBytes(final long v, final byte[] arr) {

/** Byte array conversions *******************/

static long[] convertToLongArray(final byte[] byteArr, final boolean littleEndian) {
/**
* Converts a byte array to an array of longs, taking the bytes in groups of 8.
*
* <p>Each group of 8 bytes becomes one long. If <i>bigEndian</i> is false, the first byte of a group
* is the least significant byte of its long (Little-Endian). If true, the first byte of a group is the
* most significant byte (Big-Endian).</p>
*
* <p>If the length of the byte array is not a multiple of 8, the final group has fewer than 8 bytes.
* Those bytes are converted in the same byte order and are flush right in the final long; its unused
* high-order bytes are zero. For example, the final group {9, 10, 11, 12} becomes
* 0x000000000C0B0A09 if Little-Endian and 0x00000000090A0B0C if Big-Endian.</p>
*
* @param byteArr the given byte array
* @param bigEndian if true, the bytes of each group are in Big-Endian order, otherwise Little-Endian.
* @return an array of ceiling(byteArr.length / 8) longs.
*/
static long[] convertToLongArray(final byte[] byteArr, final boolean bigEndian) {
final int len = byteArr.length;
final long[] longArr = new long[(len / 8) + ((len % 8) != 0 ? 1 : 0)];
int off = 0;
int longArrIdx = 0;
while (off < len) {
final int rem = Math.min(len - 1 - off, 7);
final int end = Math.min(off + 8, len); //exclusive
long tgt = 0;
if (littleEndian) {
for (int j = off + rem, k = 0; j >= off; --j, k++) {
tgt |= (byteArr[j] & 0XFFL) << (k * 8);
}
} else { //BE
for (int j = off + rem, k = rem; j >= off; --j, k--) {
tgt |= (byteArr[j] & 0XFFL) << (k * 8);
}
for (int j = off; j < end; j++) {
final int shift = bigEndian ? (end - 1 - j) * 8 : (j - off) * 8;
tgt |= (byteArr[j] & 0XFFL) << shift;
}
off += 8;
longArr[longArrIdx++] = tgt;
Expand Down
21 changes: 13 additions & 8 deletions src/main/java/org/apache/datasketches/kll/KllPreambleUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ final class KllPreambleUtil {

private KllPreambleUtil() {}

private static final String ITEMS_SERDE_MSG = "SerDe parameter must not be null for ITEMS_SKETCH.";

// Preamble byte addresses
static final int PREAMBLE_INTS_BYTE_ADR = 0;
static final int SER_VER_BYTE_ADR = 1;
Expand Down Expand Up @@ -224,7 +226,7 @@ static String toString(final MemorySegment seg, final SketchType sketchType, fin
static <T> String toString(final MemorySegment seg, final SketchType sketchType, final boolean includeData,
final ArrayOfItemsSerDe<T> serDe) {
if (sketchType == KLL_ITEMS_SKETCH) {
Objects.requireNonNull(serDe, "SerDe parameter must not be null for ITEMS_SKETCH.");
Objects.requireNonNull(serDe, ITEMS_SERDE_MSG);
}
final KllMemorySegmentValidate segVal = new KllMemorySegmentValidate(seg, sketchType, serDe);
final SketchStructure myStructure = segVal.sketchStructure;
Expand Down Expand Up @@ -359,10 +361,11 @@ static <T> String toString(final MemorySegment seg, final SketchType sketchType,
sb.append(seg.get(JAVA_LONG_UNALIGNED, offsetBytes)).append(LS);
offsetBytes += typeBytes;
} else { //ITEMS_SKETCH
sb.append(serDe.deserializeFromMemorySegment(seg, offsetBytes, 1)[0]).append(LS);
offsetBytes += serDe.sizeOf(seg, offsetBytes, 1);
sb.append(serDe.deserializeFromMemorySegment(seg, offsetBytes, 1)[0]).append(LS);
offsetBytes += serDe.sizeOf(seg, offsetBytes, 1);
final ArrayOfItemsSerDe<T> itemsSerDe = Objects.requireNonNull(serDe, ITEMS_SERDE_MSG);
sb.append(itemsSerDe.deserializeFromMemorySegment(seg, offsetBytes, 1)[0]).append(LS);
offsetBytes += itemsSerDe.sizeOf(seg, offsetBytes, 1);
sb.append(itemsSerDe.deserializeFromMemorySegment(seg, offsetBytes, 1)[0]).append(LS);
offsetBytes += itemsSerDe.sizeOf(seg, offsetBytes, 1);
}

sb.append("RETAINED DATA").append(LS);
Expand All @@ -383,9 +386,10 @@ static <T> String toString(final MemorySegment seg, final SketchType sketchType,
offsetBytes += typeBytes;
}
} else { //ITEMS_SKETCH
final T[] itemsArr = serDe.deserializeFromMemorySegment(seg, offsetBytes, retainedItems);
final ArrayOfItemsSerDe<T> itemsSerDe = Objects.requireNonNull(serDe, ITEMS_SERDE_MSG);
final T[] itemsArr = itemsSerDe.deserializeFromMemorySegment(seg, offsetBytes, retainedItems);
for (int i = 0; i < itemsArr.length; i++) {
sb.append(i + ", " + serDe.toString(itemsArr[i])).append(LS);
sb.append(i + ", " + itemsSerDe.toString(itemsArr[i])).append(LS);
}
}

Expand All @@ -399,7 +403,8 @@ static <T> String toString(final MemorySegment seg, final SketchType sketchType,
} else if (sketchType == KLL_LONGS_SKETCH) {
sb.append(seg.get(JAVA_LONG_UNALIGNED, DATA_START_ADR_SINGLE_ITEM)).append(LS);
} else { //ITEMS_SKETCH
sb.append(serDe.deserializeFromMemorySegment(seg, DATA_START_ADR_SINGLE_ITEM, 1)[0]).append(LS);
final ArrayOfItemsSerDe<T> itemsSerDe = Objects.requireNonNull(serDe, ITEMS_SERDE_MSG);
sb.append(itemsSerDe.deserializeFromMemorySegment(seg, DATA_START_ADR_SINGLE_ITEM, 1)[0]).append(LS);
}

} else { //COMPACT_EMPTY
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ public String toString() {
// gadgetBytes will be null only if gadget_ == null AND empty == true
public byte[] toByteArray(final ArrayOfItemsSerDe<T> serDe, final Class<?> clazz) {
final int preLongs, outBytes;
final boolean empty = gadget_ == null;
final byte[] gadgetBytes = (gadget_ != null ? gadget_.toByteArray(serDe, clazz) : null);
final byte[] gadgetBytes = (gadget_ == null) ? null : gadget_.toByteArray(serDe, clazz);
final boolean empty = gadgetBytes == null;

if (empty) {
preLongs = Family.RESERVOIR_UNION.getMinPreLongs();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,8 @@ public String toString() {
// gadgetBytes will be null only if gadget_ == null AND empty == true
public byte[] toByteArray() {
final int preLongs, outBytes;
final boolean empty = gadget_ == null;
final byte[] gadgetBytes = (gadget_ != null ? gadget_.toByteArray() : null);
final byte[] gadgetBytes = (gadget_ == null) ? null : gadget_.toByteArray();
final boolean empty = gadgetBytes == null;

if (empty) {
preLongs = Family.RESERVOIR_UNION.getMinPreLongs();
Expand Down
22 changes: 21 additions & 1 deletion src/test/java/org/apache/datasketches/common/UtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import org.testng.Assert;
import org.testng.annotations.Test;

Expand Down Expand Up @@ -431,22 +434,39 @@ public void checkExactLog2OfIntWithArg() {
static void checkConvertToLongArray() {
final byte[] arr = {1,2,3,4,5,6,7,8,9,10,11,12};

//Little-Endian; the 4-byte tail is flush right
long[] out = convertToLongArray(arr, false);
assertEquals(out.length, 2);
String s = zeroPad(Long.toHexString(out[0]), 16);
assertEquals(s, "0807060504030201");
s = zeroPad(Long.toHexString(out[1]), 16);
assertEquals(s, "000000000c0b0a09");

//Big-Endian; the 4-byte tail is flush right
out = convertToLongArray(arr, true);
assertEquals(out.length, 2);
s = zeroPad(Long.toHexString(out[0]), 16);
assertEquals(s, "0102030405060708");
s = zeroPad(Long.toHexString(out[1]), 16);
assertEquals(s, "00000000090a0b0c");

//full groups agree with ByteBuffer in both byte orders
final byte[] arr16 = new byte[16];
for (int i = 0; i < 16; i++) { arr16[i] = (byte) (0xF0 + i); } //high bit set, to check sign handling
for (final boolean bigEndian : new boolean[] {false, true}) {
final ByteBuffer bb = ByteBuffer.wrap(arr16).order(bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
out = convertToLongArray(arr16, bigEndian);
assertEquals(out.length, 2);
assertEquals(out[0], bb.getLong(0));
assertEquals(out[1], bb.getLong(8));
}

assertEquals(convertToLongArray(new byte[0], true).length, 0);
}

@Test
static void checkCeilingMultiple2expK() {
final long n = (1 << 36) - 1L;
final long n = (1L << 36) - 1L;
final int k = 6;
final long v = ceilingMultiple2expK(n, k);
final long v2 = (long)Math.ceil(n / (double)(1 << k));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ public void checkBytes() {
final MemorySegment seg = MemorySegment.ofArray(new byte[n * Byte.BYTES]);
final PositionalSegment posSeg = PositionalSegment.wrap(seg);
for (int i = 0; i < (n/2); i++) { posSeg.setByte((byte)i); }
for (int i = n/2; i < n; i++) { posSeg.setByte(i * Byte.BYTES, (byte)i); }
for (int i = n/2; i < n; i++) { posSeg.setByte((long) i * Byte.BYTES, (byte)i); }
posSeg.resetPosition();
for (int i = 0; i < n; i++) {
final byte v1 = posSeg.getByte(i * Byte.BYTES);
final byte v1 = posSeg.getByte((long) i * Byte.BYTES);
final byte v2 = posSeg.getByte();
assertEquals(v1, v2);
assertEquals(v2, i);
Expand All @@ -57,7 +57,7 @@ public void checkBytes() {

final MemorySegment seg2 = posSeg.getMemorySegment();
for (int i = 0; i < n; i++) {
assertEquals(seg2.get(JAVA_BYTE, i * Byte.BYTES), (byte)i);
assertEquals(seg2.get(JAVA_BYTE, (long) i * Byte.BYTES), (byte)i);
}
}

Expand All @@ -67,10 +67,10 @@ public void checkChars() {
final MemorySegment seg = MemorySegment.ofArray(new byte[n * Character.BYTES]);
final PositionalSegment posSeg = PositionalSegment.wrap(seg);
for (int i = 0; i < (n/2); i++) { posSeg.setChar((char)i); }
for (int i = n/2; i < n; i++) { posSeg.setChar(i * Character.BYTES, (char)i); }
for (int i = n/2; i < n; i++) { posSeg.setChar((long) i * Character.BYTES, (char)i); }
posSeg.resetPosition();
for (int i = 0; i < n; i++) {
final int v1 = posSeg.getChar(i *Character.BYTES);
final int v1 = posSeg.getChar((long) i * Character.BYTES);
final int v2 = posSeg.getChar();
assertEquals(v1, v2);
assertEquals(v2, i);
Expand All @@ -84,7 +84,7 @@ public void checkChars() {

final MemorySegment seg2 = posSeg.getMemorySegment();
for (int i = 0; i < n; i++) {
assertEquals(seg2.get(JAVA_CHAR_UNALIGNED, i * Character.BYTES), (char)i);
assertEquals(seg2.get(JAVA_CHAR_UNALIGNED, (long) i * Character.BYTES), (char)i);
}
}

Expand All @@ -94,10 +94,10 @@ public void checkShorts() {
final MemorySegment seg = MemorySegment.ofArray(new byte[n * Short.BYTES]);
final PositionalSegment posSeg = PositionalSegment.wrap(seg);
for (int i = 0; i < (n/2); i++) { posSeg.setShort((short)i); }
for (int i = n/2; i < n; i++) { posSeg.setShort(i * Short.BYTES, (short)i); }
for (int i = n/2; i < n; i++) { posSeg.setShort((long) i * Short.BYTES, (short)i); }
posSeg.resetPosition();
for (int i = 0; i < n; i++) {
final int v1 = posSeg.getShort(i *Short.BYTES);
final int v1 = posSeg.getShort((long) i * Short.BYTES);
final int v2 = posSeg.getShort();
assertEquals(v1, v2);
assertEquals(v2, i);
Expand All @@ -111,7 +111,7 @@ public void checkShorts() {

final MemorySegment seg2 = posSeg.getMemorySegment();
for (int i = 0; i < n; i++) {
assertEquals(seg2.get(JAVA_SHORT_UNALIGNED, i * Short.BYTES), (short)i);
assertEquals(seg2.get(JAVA_SHORT_UNALIGNED, (long) i * Short.BYTES), (short)i);
}
}

Expand All @@ -121,10 +121,10 @@ public void checkInts() {
final MemorySegment seg = MemorySegment.ofArray(new byte[n * Integer.BYTES]);
final PositionalSegment posSeg = PositionalSegment.wrap(seg);
for (int i = 0; i < (n/2); i++) { posSeg.setInt((int)i); }
for (int i = n/2; i < n; i++) { posSeg.setInt(i * Integer.BYTES, (int)i); }
for (int i = n/2; i < n; i++) { posSeg.setInt((long) i * Integer.BYTES, (int)i); }
posSeg.resetPosition();
for (int i = 0; i < n; i++) {
final int v1 = posSeg.getInt(i * Integer.BYTES);
final int v1 = posSeg.getInt((long) i * Integer.BYTES);
final int v2 = posSeg.getInt();
assertEquals(v1, v2);
assertEquals(v2, i);
Expand All @@ -138,7 +138,7 @@ public void checkInts() {

final MemorySegment seg2 = posSeg.getMemorySegment();
for (int i = 0; i < n; i++) {
assertEquals(seg2.get(JAVA_INT_UNALIGNED, i * Integer.BYTES), (int)i);
assertEquals(seg2.get(JAVA_INT_UNALIGNED, (long) i * Integer.BYTES), (int)i);
}
}

Expand All @@ -149,10 +149,10 @@ public void checkLongs() {
final MemorySegment seg = MemorySegment.ofArray(new byte[n * Long.BYTES]);
final PositionalSegment posSeg = PositionalSegment.wrap(seg);
for (int i = 0; i < (n/2); i++) { posSeg.setLong(i); }
for (int i = n/2; i < n; i++) { posSeg.setLong(i * Long.BYTES, i); }
for (int i = n/2; i < n; i++) { posSeg.setLong((long) i * Long.BYTES, i); }
posSeg.resetPosition();
for (int i = 0; i < n; i++) {
final long v1 = posSeg.getLong(i * Long.BYTES);
final long v1 = posSeg.getLong((long) i * Long.BYTES);
final long v2 = posSeg.getLong();
assertEquals(v1, v2);
assertEquals(v2, i);
Expand All @@ -166,7 +166,7 @@ public void checkLongs() {

final MemorySegment seg2 = posSeg.getMemorySegment();
for (int i = 0; i < n; i++) {
assertEquals(seg2.get(JAVA_LONG_UNALIGNED, i * Long.BYTES), i);
assertEquals(seg2.get(JAVA_LONG_UNALIGNED, (long) i * Long.BYTES), i);
}
}

Expand All @@ -176,10 +176,10 @@ public void checkFloats() {
final MemorySegment seg = MemorySegment.ofArray(new byte[n * Float.BYTES]);
final PositionalSegment posSeg = PositionalSegment.wrap(seg);
for (int i = 0; i < (n/2); i++) { posSeg.setFloat(i); }
for (int i = n/2; i < n; i++) { posSeg.setFloat(i * Float.BYTES, i); }
for (int i = n/2; i < n; i++) { posSeg.setFloat((long) i * Float.BYTES, i); }
posSeg.resetPosition();
for (int i = 0; i < n; i++) {
final float v1 = posSeg.getFloat(i * Float.BYTES);
final float v1 = posSeg.getFloat((long) i * Float.BYTES);
final float v2 = posSeg.getFloat();
assertEquals(v1, v2);
assertEquals(v2, i);
Expand All @@ -193,7 +193,7 @@ public void checkFloats() {

final MemorySegment seg2 = posSeg.getMemorySegment();
for (int i = 0; i < n; i++) {
assertEquals(seg2.get(JAVA_FLOAT_UNALIGNED, i * Float.BYTES), i);
assertEquals(seg2.get(JAVA_FLOAT_UNALIGNED, (long) i * Float.BYTES), i);
}
}

Expand All @@ -203,10 +203,10 @@ public void checkDoubles() {
final MemorySegment seg = MemorySegment.ofArray(new byte[n * Double.BYTES]);
final PositionalSegment posSeg = PositionalSegment.wrap(seg);
for (int i = 0; i < (n/2); i++) { posSeg.setDouble(i); }
for (int i = n/2; i < n; i++) { posSeg.setDouble(i * Double.BYTES, i); }
for (int i = n/2; i < n; i++) { posSeg.setDouble((long) i * Double.BYTES, i); }
posSeg.resetPosition();
for (int i = 0; i < n; i++) {
final double v1 = posSeg.getDouble(i * Double.BYTES);
final double v1 = posSeg.getDouble((long) i * Double.BYTES);
final double v2 = posSeg.getDouble();
assertEquals(v1, v2);
assertEquals(v2, i);
Expand All @@ -220,7 +220,7 @@ public void checkDoubles() {

final MemorySegment seg2 = posSeg.getMemorySegment();
for (int i = 0; i < n; i++) {
assertEquals(seg2.get(JAVA_DOUBLE_UNALIGNED, i * Double.BYTES), i);
assertEquals(seg2.get(JAVA_DOUBLE_UNALIGNED, (long) i * Double.BYTES), i);
}
}

Expand Down
14 changes: 7 additions & 7 deletions src/test/java/org/apache/datasketches/cpc/CpcWrapperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ public void check() {
final CpcSketch sk1 = new CpcSketch(lgK);
final CpcSketch sk2 = new CpcSketch(lgK);
final CpcSketch skD = new CpcSketch(lgK);
final double dEst = skD.getEstimate();
final double dlb = skD.getLowerBound(2);
final double dub = skD.getUpperBound(2);
assertEquals(skD.getEstimate(), 0.0);
assertEquals(skD.getLowerBound(2), 0.0);
assertEquals(skD.getUpperBound(2), 0.0);

final int n = 100000;
for (int i = 0; i < n; i++) {
Expand All @@ -56,9 +56,9 @@ public void check() {

final CpcUnion union = new CpcUnion(lgK);
final CpcSketch result = union.getResult();
final double uEst = result.getEstimate();
final double ulb = result.getLowerBound(2);
final double uub = result.getUpperBound(2);
assertEquals(result.getEstimate(), 0.0);
assertEquals(result.getLowerBound(2), 0.0);
assertEquals(result.getUpperBound(2), 0.0);
union.update(sk1);
union.update(sk2);
final CpcSketch merged = union.getResult();
Expand Down Expand Up @@ -90,7 +90,7 @@ public void checkIsCompressed() {
final byte[] byteArr = sk.toByteArray();
byteArr[5] &= (byte) -3;
try {
final CpcWrapper wrapper = new CpcWrapper(MemorySegment.ofArray(byteArr));
new CpcWrapper(MemorySegment.ofArray(byteArr));
fail();
} catch (final AssertionError e) {}
}
Expand Down
8 changes: 4 additions & 4 deletions src/test/java/org/apache/datasketches/hll/HllSketchTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,13 @@ private static void checkSerSizes(final int lgConfigK, final TgtHllType tgtHllTy
@Test
public void checkConfigKLimits() {
try {
final HllSketch sk = new HllSketch(HllUtil.MIN_LOG_K - 1);
new HllSketch(HllUtil.MIN_LOG_K - 1);
fail();
} catch (final SketchesArgumentException e) {
//expected
}
try {
final HllSketch sk = new HllSketch(HllUtil.MAX_LOG_K + 1);
new HllSketch(HllUtil.MAX_LOG_K + 1);
fail();
} catch (final SketchesArgumentException e) {
//expected
Expand Down Expand Up @@ -303,7 +303,7 @@ public void checkMemorySegmentNotLargeEnough() {
final int bytes = getMaxUpdatableSerializationBytes(8, TgtHllType.HLL_8);
final MemorySegment wseg = MemorySegment.ofArray(new byte[bytes -1]);
try {
final HllSketch sk = new HllSketch(8, TgtHllType.HLL_8, wseg);
new HllSketch(8, TgtHllType.HLL_8, wseg);
fail();
} catch (final SketchesArgumentException e) {
//OK
Expand Down Expand Up @@ -415,7 +415,7 @@ public void checkWritableWrapOfCompact() {
final HllSketch sk = new HllSketch();
final byte[] byteArr = sk.toCompactByteArray();
final MemorySegment wseg = MemorySegment.ofArray(byteArr);
final HllSketch sk2 = HllSketch.writableWrap(wseg);
HllSketch.writableWrap(wseg);
}

@SuppressWarnings("unused")
Expand Down
Loading
Loading