public static Optional<BitMap[]> readBitMapsFromBuffer(ByteBuffer buffer, int columns, int size) {
    if (!buffer.hasRemaining()) {
      return Optional.empty();
    }
    BitMap[] bitMaps = new BitMap[columns];
    for (int i = 0; i < columns; i++) {
      boolean hasBitMap = BytesUtils.byteToBool(buffer.get());
      if (hasBitMap) {
        byte[] bytes = new byte[BitMap.getSizeOfBytes(size)];
        for (int j = 0; j < bytes.length; j++) {
          bytes[j] = buffer.get();
        }
        bitMaps[i] = new BitMap(size, bytes);
      }
    }
    return Optional.of(bitMaps);
  }
To fetch required amounts of data and combine them through List

@param queryExecution used to get TsBlock from and judge whether there is more data.
@param fetchSize wanted row size
@return pair.left is serialized TsBlock pair.right indicates if the read finished
@throws IoTDBException IoTDBException may be thrown if error happened while getting TsBlock
    from IQueryExecution
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/QueryDataSetUtils.java