in src/main/java/org/apache/datasketches/tuple/QuickSelectSketch.java [224:294]
long validate(
final Memory mem,
final SummaryDeserializer<?> deserializer) {
Objects.requireNonNull(mem, "SourceMemory must not be null.");
Objects.requireNonNull(deserializer, "Deserializer must not be null.");
checkBounds(0, 8, mem.getCapacity());
int offset = 0;
final byte preambleLongs = mem.getByte(offset++); //byte 0 PreLongs
final byte version = mem.getByte(offset++); //byte 1 SerVer
final byte familyId = mem.getByte(offset++); //byte 2 FamID
SerializerDeserializer.validateFamily(familyId, preambleLongs);
if (version > serialVersionUID) {
throw new SketchesArgumentException(
"Unsupported serial version. Expected: " + serialVersionUID + " or lower, actual: "
+ version);
}
SerializerDeserializer.validateType(mem.getByte(offset++), //byte 3
SerializerDeserializer.SketchType.QuickSelectSketch);
final byte flags = mem.getByte(offset++); //byte 4
final boolean isBigEndian = (flags & 1 << Flags.IS_BIG_ENDIAN.ordinal()) > 0;
if (isBigEndian ^ ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)) {
throw new SketchesArgumentException("Endian byte order mismatch");
}
myNomEntries = 1 << mem.getByte(offset++); //byte 5
myLgCurrentCapacity = mem.getByte(offset++); //byte 6
myLgResizeFactor = mem.getByte(offset++); //byte 7
checkBounds(0, preambleLongs * 8L, mem.getCapacity());
final boolean isInSamplingMode = (flags & 1 << Flags.IS_IN_SAMPLING_MODE.ordinal()) > 0;
mySamplingProbability = isInSamplingMode ? mem.getFloat(offset) : 1f; //bytes 8 - 11
if (isInSamplingMode) {
offset += Float.BYTES;
}
final boolean isThetaIncluded = (flags & 1 << Flags.IS_THETA_INCLUDED.ordinal()) > 0;
if (isThetaIncluded) {
myThetaLong = mem.getLong(offset);
offset += Long.BYTES;
} else {
myThetaLong = (long) (Long.MAX_VALUE * (double) mySamplingProbability);
}
int count = 0;
final boolean hasEntries = (flags & (1 << Flags.HAS_ENTRIES.ordinal())) > 0;
if (hasEntries) {
count = mem.getInt(offset);
offset += Integer.BYTES;
}
final int currentCapacity = 1 << myLgCurrentCapacity;
myHashTable = new long[currentCapacity];
for (int i = 0; i < count; i++) {
final long hash = mem.getLong(offset);
offset += Long.BYTES;
final Memory memRegion = mem.region(offset, mem.getCapacity() - offset);
final DeserializeResult<?> summaryResult = deserializer.heapifySummary(memRegion);
final S summary = (S) summaryResult.getObject();
offset += summaryResult.getSize();
//in-place equivalent to insert(hash, summary):
final int index = HashOperations.hashInsertOnly(myHashTable, myLgCurrentCapacity, hash);
if (mySummaryTable == null) {
mySummaryTable = (S[]) Array.newInstance(summary.getClass(), myHashTable.length);
}
mySummaryTable[index] = summary;
myRetEntries++;
myEmpty = false;
}
myEmpty = (flags & 1 << Flags.IS_EMPTY.ordinal()) > 0;
myRebuildThreshold = setRebuildThreshold(myHashTable, myNomEntries);
return myThetaLong;
}