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());
}