public Map<Long, Pair<Path, TimeseriesMetadata>> getAllTimeseriesMetadataWithOffset()
        throws IOException {
      if (tsFileMetaData == null) {
        readFileMetadata();
      }
      Map<Long, Pair<Path, TimeseriesMetadata>> timeseriesMetadataMap = new TreeMap<>();
      for (MetadataIndexNode metadataIndexNode :
          tsFileMetaData.getTableMetadataIndexNodeMap().values()) {
        List<IMetadataIndexEntry> metadataIndexEntryList = metadataIndexNode.getChildren();
        for (int i = 0; i < metadataIndexEntryList.size(); i++) {
          IMetadataIndexEntry metadataIndexEntry = metadataIndexEntryList.get(i);
          long endOffset = metadataIndexNode.getEndOffset();
          if (i != metadataIndexEntryList.size() - 1) {
            endOffset = metadataIndexEntryList.get(i + 1).getOffset();
          }
          ByteBuffer buffer = readData(metadataIndexEntry.getOffset(), endOffset);
          generateMetadataIndexWithOffset(
              metadataIndexEntry.getOffset(),
              metadataIndexEntry,
              buffer,
              null,
              metadataIndexNode.getNodeType(),
              timeseriesMetadataMap,
              false);
        }
      }

      return timeseriesMetadataMap;
    }
Traverse the metadata index from MetadataIndexEntry to get TimeseriesMetadatas

@param metadataIndex MetadataIndexEntry
@param buffer byte buffer
@param deviceId String
@param timeseriesMetadataMap map: deviceId -> timeseriesMetadata list
@param needChunkMetadata deserialize chunk metadata list or not
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/tools/TsFileSelfCheckTool.java