in src/main/java/org/apache/datasketches/theta/CompactOperations.java [117:195]
static CompactSketch memoryToCompact(
final Memory srcMem,
final boolean dstOrdered,
final WritableMemory dstMem)
{
//extract Pre0 fields and Flags from srcMem
final int srcPreLongs = extractPreLongs(srcMem);
final int srcSerVer = extractSerVer(srcMem); //not used
final int srcFamId = extractFamilyID(srcMem);
final int srcLgArrLongs = extractLgArrLongs(srcMem);
final int srcFlags = extractFlags(srcMem);
final short srcSeedHash = (short) extractSeedHash(srcMem);
//srcFlags
final boolean srcReadOnlyFlag = (srcFlags & READ_ONLY_FLAG_MASK) > 0;
final boolean srcEmptyFlag = (srcFlags & EMPTY_FLAG_MASK) > 0;
final boolean srcCompactFlag = (srcFlags & COMPACT_FLAG_MASK) > 0;
final boolean srcOrderedFlag = (srcFlags & ORDERED_FLAG_MASK) > 0;
final boolean srcSingleFlag = (srcFlags & SINGLEITEM_FLAG_MASK) > 0;
final boolean single = srcSingleFlag
|| SingleItemSketch.otherCheckForSingleItem(srcPreLongs, srcSerVer, srcFamId, srcFlags);
//extract pre1 and pre2 fields
final int curCount = single ? 1 : (srcPreLongs > 1) ? extractCurCount(srcMem) : 0;
final long thetaLong = (srcPreLongs > 2) ? extractThetaLong(srcMem) : Long.MAX_VALUE;
//do some basic checks ...
if (srcEmptyFlag) { assert (curCount == 0) && (thetaLong == Long.MAX_VALUE); }
if (single) { assert (curCount == 1) && (thetaLong == Long.MAX_VALUE); }
checkFamilyAndFlags(srcFamId, srcCompactFlag, srcReadOnlyFlag);
//dispatch empty and single cases
//Note: for empty and single we always output the ordered form.
final boolean dstOrderedOut = (srcEmptyFlag || single) ? true : dstOrdered;
if (srcEmptyFlag) {
if (dstMem != null) {
dstMem.putByteArray(0, EmptyCompactSketch.EMPTY_COMPACT_SKETCH_ARR, 0, 8);
return new DirectCompactSketch(dstMem);
} else {
return EmptyCompactSketch.getInstance();
}
}
if (single) {
final long hash = srcMem.getLong(srcPreLongs << 3);
final SingleItemSketch sis = new SingleItemSketch(hash, srcSeedHash);
if (dstMem != null) {
dstMem.putByteArray(0, sis.toByteArray(),0, 16);
return new DirectCompactSketch(dstMem);
} else { //heap
return sis;
}
}
//extract hashArr > 1
final long[] hashArr;
if (srcCompactFlag) {
hashArr = new long[curCount];
srcMem.getLongArray(srcPreLongs << 3, hashArr, 0, curCount);
} else { //update sketch, thus hashTable form
final int srcCacheLen = 1 << srcLgArrLongs;
final long[] tempHashArr = new long[srcCacheLen];
srcMem.getLongArray(srcPreLongs << 3, tempHashArr, 0, srcCacheLen);
hashArr = compactCache(tempHashArr, curCount, thetaLong, dstOrderedOut);
}
final int flagsOut = READ_ONLY_FLAG_MASK | COMPACT_FLAG_MASK
| ((dstOrderedOut) ? ORDERED_FLAG_MASK : 0);
//load the destination.
if (dstMem != null) {
final Memory tgtMem = loadCompactMemory(hashArr, srcSeedHash, curCount, thetaLong, dstMem,
(byte)flagsOut, srcPreLongs);
return new DirectCompactSketch(tgtMem);
} else { //heap
return new HeapCompactSketch(hashArr, srcEmptyFlag, srcSeedHash, curCount, thetaLong,
dstOrderedOut);
}
}