long validate()

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;
    }