docs: @Override
    public void serialize(ByteBuffer buffer) {
      ByteBuffer buf = buffer.order() == LITTLE_ENDIAN ? buffer : buffer.slice().order(LITTLE_ENDIAN);
      int startOffset;
      boolean hasrun = hasRunCompression();
      if (hasrun) {
        buf.putInt(SERIAL_COOKIE | ((size - 1) << 16));
        int offset = buf.position();
        for (int i = 0; i < size; i += 8) {
          int runMarker = 0;
          for (int j = 0; j < 8 && i + j < size; ++j) {
            if (values[i + j] instanceof MappeableRunContainer) {
              runMarker |= (1 << j);
            }
          }
          buf.put((byte)runMarker);
        }
        int runMarkersLength = buf.position() - offset;
        if (this.size < NO_OFFSET_THRESHOLD) {
          startOffset = 4 + 4 * this.size + runMarkersLength;
        } else {
          startOffset = 4 + 8 * this.size + runMarkersLength;
        }
      } else { // backwards compatibility
        buf.putInt(SERIAL_COOKIE_NO_RUNCONTAINER);
        buf.putInt(size);
        startOffset = 4 + 4 + 4 * this.size + 4 * this.size;
      }
      for (int k = 0; k < size; ++k) {
        buf.putShort(this.keys[k]);
        buf.putShort((short) (this.values[k].getCardinality() - 1));
      }
      if ((!hasrun) || (this.size >= NO_OFFSET_THRESHOLD)) {
        // writing the containers offsets
        for (int k = 0; k < this.size; ++k) {
          buf.putInt(startOffset);
          startOffset = startOffset + this.values[k].getArraySizeInBytes();
        }
      }
      for (int k = 0; k < size; ++k) {
        values[k].writeArray(buf);
      }
      if (buf != buffer) {
        buffer.position(buffer.position() + buf.position());
      }
    }