docs: @SuppressWarnings("null")
    @Override
    public byte[] toByteArray() {
      byte[][] summariesBytes = null;
      int summariesBytesLength = 0;
      if (count_ > 0) {
        summariesBytes = new byte[count_][];
        int i = 0;
        for (int j = 0; j < summaries_.length; j++) {
          if (summaries_[j] != null) {
            summariesBytes[i] = summaries_[j].toByteArray();
            summariesBytesLength += summariesBytes[i].length;
            i++;
          }
        }
      }
      int sizeBytes =
          Byte.BYTES // preamble longs
        + Byte.BYTES // serial version
        + Byte.BYTES // family
        + Byte.BYTES // sketch type
        + Byte.BYTES // flags
        + Byte.BYTES // log2(nomEntries)
        + Byte.BYTES // log2(currentCapacity)
        + Byte.BYTES; // log2(resizeFactor)
      if (isInSamplingMode()) {
        sizeBytes += Float.BYTES; // samplingProbability
      }
      final boolean isThetaIncluded = isInSamplingMode()
          ? theta_ < samplingProbability_ : theta_ < Long.MAX_VALUE;
      if (isThetaIncluded) {
        sizeBytes += Long.BYTES;
      }
      if (count_ > 0) {
        sizeBytes += Integer.BYTES; // count
      }
      sizeBytes += (Long.BYTES * count_) + summariesBytesLength;
      final byte[] bytes = new byte[sizeBytes];
      int offset = 0;
      bytes[offset++] = PREAMBLE_LONGS;
      bytes[offset++] = serialVersionUID;
      bytes[offset++] = (byte) Family.TUPLE.getID();
      bytes[offset++] = (byte) SerializerDeserializer.SketchType.QuickSelectSketch.ordinal();
      final boolean isBigEndian = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN);
      bytes[offset++] = (byte) (
        (isBigEndian ? 1 << Flags.IS_BIG_ENDIAN.ordinal() : 0)
        | (isInSamplingMode() ? 1 << Flags.IS_IN_SAMPLING_MODE.ordinal() : 0)
        | (isEmpty_ ? 1 << Flags.IS_EMPTY.ordinal() : 0)
        | (count_ > 0 ? 1 << Flags.HAS_ENTRIES.ordinal() : 0)
        | (isThetaIncluded ? 1 << Flags.IS_THETA_INCLUDED.ordinal() : 0)
      );
      bytes[offset++] = (byte) Integer.numberOfTrailingZeros(nomEntries_);
      bytes[offset++] = (byte) lgCurrentCapacity_;
      bytes[offset++] = (byte) lgResizeFactor_;
      if (samplingProbability_ < 1f) {
        ByteArrayUtil.putFloatLE(bytes, offset, samplingProbability_);
        offset += Float.BYTES;
      }
      if (isThetaIncluded) {
        ByteArrayUtil.putLongLE(bytes, offset, theta_);
        offset += Long.BYTES;
      }
      if (count_ > 0) {
        ByteArrayUtil.putIntLE(bytes, offset, count_);
        offset += Integer.BYTES;
      }
      if (count_ > 0) {
        int i = 0;
        for (int j = 0; j < keys_.length; j++) {
          if (summaries_[j] != null) {
            ByteArrayUtil.putLongLE(bytes, offset, keys_[j]);
            offset += Long.BYTES;
            System.arraycopy(summariesBytes[i], 0, bytes, offset, summariesBytes[i].length);
            offset += summariesBytes[i].length;
            i++;
          }
        }
      }
      return bytes;
    }