private void readChunkMetadataAndConstructIndexTree()

in java/tsfile/src/main/java/org/apache/tsfile/write/writer/TsFileIOWriter.java [434:529]


  private void readChunkMetadataAndConstructIndexTree() throws IOException {
    if (tempOutput != null) {
      tempOutput.close();
    }
    long metaOffset = out.getPosition();

    // serialize the SEPARATOR of MetaData
    ReadWriteIOUtils.write(MetaMarker.SEPARATOR, out.wrapAsStream());

    TSMIterator tsmIterator = getTSMIterator();
    Map<IDeviceID, MetadataIndexNode> deviceMetadataIndexMap = new TreeMap<>();
    Queue<MetadataIndexNode> measurementMetadataIndexQueue = new ArrayDeque<>();
    IDeviceID currentDevice = null;
    IDeviceID prevDevice = null;
    Path currentPath = null;
    MetadataIndexNode currentIndexNode =
        new MetadataIndexNode(MetadataIndexNodeType.LEAF_MEASUREMENT);
    int seriesIdxForCurrDevice = 0;
    BloomFilter filter =
        BloomFilter.getEmptyBloomFilter(
            TSFileDescriptor.getInstance().getConfig().getBloomFilterErrorRate(), pathCount);

    while (tsmIterator.hasNext()) {
      // read in all chunk metadata of one series
      // construct the timeseries metadata for this series
      Pair<Path, TimeseriesMetadata> timeseriesMetadataPair = tsmIterator.next();
      TimeseriesMetadata timeseriesMetadata = timeseriesMetadataPair.right;
      currentPath = timeseriesMetadataPair.left;

      // build bloom filter
      filter.add(currentPath);
      // construct the index tree node for the series
      currentDevice = currentPath.getIDeviceID();
      if (!currentDevice.equals(prevDevice)) {
        if (prevDevice != null) {
          addCurrentIndexNodeToQueue(currentIndexNode, measurementMetadataIndexQueue, out);
          deviceMetadataIndexMap.put(
              prevDevice,
              generateRootNode(
                  measurementMetadataIndexQueue, out, MetadataIndexNodeType.INTERNAL_MEASUREMENT));
          currentIndexNode = new MetadataIndexNode(MetadataIndexNodeType.LEAF_MEASUREMENT);
        }
        measurementMetadataIndexQueue = new ArrayDeque<>();
        seriesIdxForCurrDevice = 0;
      }

      if (seriesIdxForCurrDevice % TS_FILE_CONFIG.getMaxDegreeOfIndexNode() == 0) {
        if (currentIndexNode.isFull()) {
          addCurrentIndexNodeToQueue(currentIndexNode, measurementMetadataIndexQueue, out);
          currentIndexNode = new MetadataIndexNode(MetadataIndexNodeType.LEAF_MEASUREMENT);
        }
        if (timeseriesMetadata.getTsDataType() != TSDataType.VECTOR) {
          currentIndexNode.addEntry(
              new MeasurementMetadataIndexEntry(currentPath.getMeasurement(), out.getPosition()));
        } else {
          currentIndexNode.addEntry(new MeasurementMetadataIndexEntry("", out.getPosition()));
        }
      }

      prevDevice = currentDevice;
      seriesIdxForCurrDevice++;
      // serialize the timeseries metadata to file
      timeseriesMetadata.serializeTo(out.wrapAsStream());
    }

    addCurrentIndexNodeToQueue(currentIndexNode, measurementMetadataIndexQueue, out);
    if (prevDevice != null) {
      deviceMetadataIndexMap.put(
          prevDevice,
          generateRootNode(
              measurementMetadataIndexQueue, out, MetadataIndexNodeType.INTERNAL_MEASUREMENT));
    }

    Map<String, Map<IDeviceID, MetadataIndexNode>> tableDeviceNodesMap =
        splitDeviceByTable(deviceMetadataIndexMap);

    // build an index root for each table
    Map<String, MetadataIndexNode> tableNodesMap = new TreeMap<>();
    for (Entry<String, Map<IDeviceID, MetadataIndexNode>> entry : tableDeviceNodesMap.entrySet()) {
      tableNodesMap.put(entry.getKey(), checkAndBuildLevelIndex(entry.getValue(), out));
    }

    TsFileMetadata tsFileMetadata = new TsFileMetadata();
    tsFileMetadata.setTableMetadataIndexNodeMap(tableNodesMap);
    tsFileMetadata.setTableSchemaMap(schema.getTableSchemaMap());
    tsFileMetadata.setMetaOffset(metaOffset);
    tsFileMetadata.setBloomFilter(filter);
    tsFileMetadata.addProperty("encryptLevel", encryptLevel);
    tsFileMetadata.addProperty("encryptType", encryptType);
    tsFileMetadata.addProperty("encryptKey", encryptKey);

    int size = tsFileMetadata.serializeTo(out.wrapAsStream());

    // write TsFileMetaData size
    ReadWriteIOUtils.write(size, out.wrapAsStream());
  }