This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch snapshot/2.2.0-251208
in repository https://gitbox.apache.org/repos/asf/tsfile.git
The following commit(s) were added to refs/heads/snapshot/2.2.0-251208 by this
push:
new fe0d9326 enhance TsFileDeviceIterator (#657)
fe0d9326 is described below
commit fe0d93261195d09ae693a8da899189b12ef3278d
Author: shuwenwei <[email protected]>
AuthorDate: Mon Dec 8 11:11:01 2025 +0800
enhance TsFileDeviceIterator (#657)
---
.../tsfile/read/LazyTsFileDeviceIterator.java | 234 +++++++++++++++++++++
.../apache/tsfile/read/TsFileDeviceIterator.java | 196 +----------------
.../apache/tsfile/read/TsFileSequenceReader.java | 7 +-
.../tsfile/read/TsFileDeviceIteratorTest.java | 15 +-
4 files changed, 264 insertions(+), 188 deletions(-)
diff --git
a/java/tsfile/src/main/java/org/apache/tsfile/read/LazyTsFileDeviceIterator.java
b/java/tsfile/src/main/java/org/apache/tsfile/read/LazyTsFileDeviceIterator.java
new file mode 100644
index 00000000..8a88f112
--- /dev/null
+++
b/java/tsfile/src/main/java/org/apache/tsfile/read/LazyTsFileDeviceIterator.java
@@ -0,0 +1,234 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tsfile.read;
+
+import org.apache.tsfile.exception.TsFileRuntimeException;
+import org.apache.tsfile.file.IMetadataIndexEntry;
+import org.apache.tsfile.file.metadata.DeviceMetadataIndexEntry;
+import org.apache.tsfile.file.metadata.IDeviceID;
+import org.apache.tsfile.file.metadata.MetadataIndexNode;
+import org.apache.tsfile.file.metadata.enums.MetadataIndexNodeType;
+import org.apache.tsfile.utils.Pair;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.function.LongConsumer;
+
+public class LazyTsFileDeviceIterator {
+ protected final TsFileSequenceReader reader;
+ protected final Iterator<MetadataIndexNode> tableMetadataIndexNodeIterator;
+ protected final ArrayDeque<Pair<IDeviceID, long[]>> queue = new
ArrayDeque<>();
+ protected final ArrayDeque<Iterator<Pair<DeviceMetadataIndexEntry, Long>>>
+ levelInternalDeviceNodeIterators = new ArrayDeque<>(4);
+ protected final LongConsumer ioSizeRecorder;
+ protected Pair<IDeviceID, long[]> currentDeviceAndMeasurementNodeOffsetPair;
+ protected MetadataIndexNode firstMeasurementNodeOfCurrentDevice;
+
+ protected static final Logger logger =
LoggerFactory.getLogger(LazyTsFileDeviceIterator.class);
+
+ public LazyTsFileDeviceIterator(TsFileSequenceReader reader) throws
IOException {
+ this(reader, null);
+ }
+
+ public LazyTsFileDeviceIterator(TsFileSequenceReader reader, LongConsumer
ioSizeRecorder)
+ throws IOException {
+ this.reader = reader;
+ this.tableMetadataIndexNodeIterator =
+
reader.readFileMetadata(ioSizeRecorder).getTableMetadataIndexNodeMap().values().iterator();
+ this.ioSizeRecorder = ioSizeRecorder;
+ }
+
+ public LazyTsFileDeviceIterator(
+ TsFileSequenceReader reader, String tableName, LongConsumer
ioSizeRecorder)
+ throws IOException {
+ this.reader = reader;
+ this.ioSizeRecorder = ioSizeRecorder;
+ MetadataIndexNode tableMetadataIndexNode =
+
reader.readFileMetadata(ioSizeRecorder).getTableMetadataIndexNode(tableName);
+ this.tableMetadataIndexNodeIterator =
+ tableMetadataIndexNode == null
+ ? Collections.emptyIterator()
+ : Collections.singleton(tableMetadataIndexNode).iterator();
+ }
+
+ public boolean hasNext() {
+ try {
+ while (true) {
+ if (!queue.isEmpty()) {
+ return true;
+ }
+
+ if (!levelInternalDeviceNodeIterators.isEmpty()) {
+ advanceInternalIterators();
+ continue;
+ }
+
+ if (!tableMetadataIndexNodeIterator.hasNext()) {
+ return false;
+ }
+ prepareNextTable();
+ }
+ } catch (IOException e) {
+ throw new TsFileRuntimeException(e);
+ }
+ }
+
+ private void advanceInternalIterators() throws IOException {
+ while (!levelInternalDeviceNodeIterators.isEmpty() && queue.isEmpty()) {
+ Iterator<Pair<DeviceMetadataIndexEntry, Long>> iterator =
+ levelInternalDeviceNodeIterators.peek();
+
+ if (!iterator.hasNext()) {
+ levelInternalDeviceNodeIterators.pop();
+ continue;
+ }
+
+ Pair<DeviceMetadataIndexEntry, Long> childEntryPair = iterator.next();
+ MetadataIndexNode node =
+ reader.readMetadataIndexNode(
+ childEntryPair.getLeft().getOffset(),
+ childEntryPair.getRight(),
+ true,
+ ioSizeRecorder);
+
+ if (node.getNodeType() == MetadataIndexNodeType.LEAF_DEVICE) {
+ getDevicesOfLeafNode(node, queue);
+ } else {
+
levelInternalDeviceNodeIterators.push(constructDeviceEntryIterator(node));
+ }
+ }
+ }
+
+ public IDeviceID next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ this.currentDeviceAndMeasurementNodeOffsetPair = queue.remove();
+ this.firstMeasurementNodeOfCurrentDevice = null;
+ return currentDeviceAndMeasurementNodeOffsetPair.getLeft();
+ }
+
+ public IDeviceID getCurrentDeviceID() {
+ if (currentDeviceAndMeasurementNodeOffsetPair == null) {
+ throw new IllegalStateException("next() must be called before accessing
current device");
+ }
+ return currentDeviceAndMeasurementNodeOffsetPair.getLeft();
+ }
+
+ public long[] getCurrentDeviceMeasurementNodeOffset() {
+ if (currentDeviceAndMeasurementNodeOffsetPair == null) {
+ throw new IllegalStateException("next() must be called before accessing
current device");
+ }
+ return this.currentDeviceAndMeasurementNodeOffsetPair.getRight();
+ }
+
+ public boolean isCurrentDeviceAligned() throws IOException {
+ return reader.isAlignedDevice(getFirstMeasurementNodeOfCurrentDevice());
+ }
+
+ public MetadataIndexNode getFirstMeasurementNodeOfCurrentDevice() throws
IOException {
+ if (currentDeviceAndMeasurementNodeOffsetPair == null) {
+ throw new IllegalStateException("next() must be called before accessing
current device");
+ }
+ if (this.firstMeasurementNodeOfCurrentDevice != null) {
+ return this.firstMeasurementNodeOfCurrentDevice;
+ }
+ long[] offsetArr = currentDeviceAndMeasurementNodeOffsetPair.getRight();
+ this.firstMeasurementNodeOfCurrentDevice =
+ reader.readMetadataIndexNode(offsetArr[0], offsetArr[1], false,
ioSizeRecorder);
+ return this.firstMeasurementNodeOfCurrentDevice;
+ }
+
+ private void prepareNextTable() throws IOException {
+ while (queue.isEmpty()
+ && levelInternalDeviceNodeIterators.isEmpty()
+ && tableMetadataIndexNodeIterator.hasNext()) {
+ MetadataIndexNode nextTableMetadataIndexNode =
tableMetadataIndexNodeIterator.next();
+
+ if
(nextTableMetadataIndexNode.getNodeType().equals(MetadataIndexNodeType.LEAF_DEVICE))
{
+ getDevicesOfLeafNode(nextTableMetadataIndexNode, queue);
+ } else {
+ levelInternalDeviceNodeIterators.push(
+ constructDeviceEntryIterator(nextTableMetadataIndexNode));
+ }
+ }
+ }
+
+ protected Iterator<Pair<DeviceMetadataIndexEntry, Long>>
constructDeviceEntryIterator(
+ MetadataIndexNode node) {
+ return new Iterator<Pair<DeviceMetadataIndexEntry, Long>>() {
+
+ int index = 0;
+
+ @Override
+ public boolean hasNext() {
+ return index < node.getChildren().size();
+ }
+
+ @Override
+ public Pair<DeviceMetadataIndexEntry, Long> next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ IMetadataIndexEntry entry = node.getChildren().get(index++);
+ if (index == node.getChildren().size()) {
+ return new Pair<>((DeviceMetadataIndexEntry) entry,
node.getEndOffset());
+ }
+ return new Pair<>(
+ (DeviceMetadataIndexEntry) entry,
node.getChildren().get(index).getOffset());
+ }
+ };
+ }
+
+ protected void getDevicesOfLeafNode(
+ MetadataIndexNode deviceLeafNode, Queue<Pair<IDeviceID, long[]>>
measurementNodeOffsetQueue) {
+ if
(!deviceLeafNode.getNodeType().equals(MetadataIndexNodeType.LEAF_DEVICE)) {
+ throw new IllegalStateException("the first param should be device leaf
node.");
+ }
+ List<IMetadataIndexEntry> childrenEntries = deviceLeafNode.getChildren();
+ for (int i = 0; i < childrenEntries.size(); i++) {
+ IMetadataIndexEntry deviceEntry = childrenEntries.get(i);
+ long childStartOffset = deviceEntry.getOffset();
+ long childEndOffset =
+ i == childrenEntries.size() - 1
+ ? deviceLeafNode.getEndOffset()
+ : childrenEntries.get(i + 1).getOffset();
+ long[] offset = {childStartOffset, childEndOffset};
+ measurementNodeOffsetQueue.offer(
+ new Pair<>(((DeviceMetadataIndexEntry) deviceEntry).getDeviceID(),
offset));
+ }
+ }
+
+ public TsFileSequenceReader getReader() {
+ return reader;
+ }
+
+ public LongConsumer getIoSizeRecorder() {
+ return ioSizeRecorder;
+ }
+}
diff --git
a/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileDeviceIterator.java
b/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileDeviceIterator.java
index fc283f26..781d233e 100644
--- a/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileDeviceIterator.java
+++ b/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileDeviceIterator.java
@@ -19,226 +19,50 @@
package org.apache.tsfile.read;
-import org.apache.tsfile.compatibility.DeserializeConfig;
-import org.apache.tsfile.exception.StopReadTsFileByInterruptException;
import org.apache.tsfile.exception.TsFileRuntimeException;
-import org.apache.tsfile.file.IMetadataIndexEntry;
-import org.apache.tsfile.file.metadata.DeviceMetadataIndexEntry;
import org.apache.tsfile.file.metadata.IDeviceID;
import org.apache.tsfile.file.metadata.MetadataIndexNode;
-import org.apache.tsfile.file.metadata.enums.MetadataIndexNodeType;
import org.apache.tsfile.utils.Pair;
-import org.apache.tsfile.utils.ReadWriteIOUtils;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.Collections;
import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Queue;
import java.util.function.LongConsumer;
public class TsFileDeviceIterator implements Iterator<Pair<IDeviceID,
Boolean>> {
-
- private final TsFileSequenceReader reader;
- private final DeserializeConfig deserializeConfig;
- private final Iterator<MetadataIndexNode> tableMetadataIndexNodeIterator;
- private final Queue<Pair<IDeviceID, long[]>> queue = new LinkedList<>();
- private final List<long[]> leafDeviceNodeOffsetList = new LinkedList<>();
- private final LongConsumer ioSizeRecorder;
- private Pair<IDeviceID, Boolean> currentDevice = null;
- private MetadataIndexNode measurementNode;
-
- private static final Logger logger =
LoggerFactory.getLogger(TsFileDeviceIterator.class);
+ private final LazyTsFileDeviceIterator lazyTsFileDeviceIterator;
public TsFileDeviceIterator(TsFileSequenceReader reader) throws IOException {
- this.reader = reader;
- this.deserializeConfig = reader.getDeserializeContext();
- this.tableMetadataIndexNodeIterator =
-
reader.readFileMetadata().getTableMetadataIndexNodeMap().values().iterator();
- this.ioSizeRecorder = null;
+ this.lazyTsFileDeviceIterator = new LazyTsFileDeviceIterator(reader);
}
public TsFileDeviceIterator(
TsFileSequenceReader reader, String tableName, LongConsumer
ioSizeRecorder)
throws IOException {
- this.reader = reader;
- this.deserializeConfig = reader.getDeserializeContext();
- this.ioSizeRecorder = ioSizeRecorder;
- MetadataIndexNode tableMetadataIndexNode =
-
reader.readFileMetadata(ioSizeRecorder).getTableMetadataIndexNode(tableName);
- this.tableMetadataIndexNodeIterator =
- tableMetadataIndexNode == null
- ? Collections.emptyIterator()
- : Collections.singleton(tableMetadataIndexNode).iterator();
- }
-
- public Pair<IDeviceID, Boolean> current() {
- return currentDevice;
+ this.lazyTsFileDeviceIterator = new LazyTsFileDeviceIterator(reader,
tableName, ioSizeRecorder);
}
@Override
public boolean hasNext() {
- try {
- prepareNextTable();
- if (!queue.isEmpty()) {
- return true;
- } else if (leafDeviceNodeOffsetList.isEmpty()) {
- // device queue is empty and all device leaf node has been read
- return false;
- } else {
- // queue is empty but there are still some devices on leaf node not
being read yet
- long[] nextDeviceLeafNodeOffset = leafDeviceNodeOffsetList.remove(0);
- getDevicesAndEntriesOfOneLeafNode(
- nextDeviceLeafNodeOffset[0], nextDeviceLeafNodeOffset[1], queue);
- return true;
- }
- } catch (IOException e) {
- throw new TsFileRuntimeException(e);
- }
- }
-
- private void prepareNextTable() throws IOException {
- if (!queue.isEmpty() || !leafDeviceNodeOffsetList.isEmpty()) {
- return;
- }
- if (!tableMetadataIndexNodeIterator.hasNext()) {
- return;
- }
- MetadataIndexNode nextTableMetadataIndexNode =
tableMetadataIndexNodeIterator.next();
-
- if
(nextTableMetadataIndexNode.getNodeType().equals(MetadataIndexNodeType.LEAF_DEVICE))
{
- getDevicesOfLeafNode(nextTableMetadataIndexNode, queue);
- } else {
- getAllDeviceLeafNodeOffset(nextTableMetadataIndexNode,
leafDeviceNodeOffsetList);
- }
+ return lazyTsFileDeviceIterator.hasNext();
}
@Override
public Pair<IDeviceID, Boolean> next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- Pair<IDeviceID, long[]> startEndPair = queue.remove();
+ IDeviceID deviceId = lazyTsFileDeviceIterator.next();
try {
// get the first measurement node of this device, to know if the device
is aligned
- this.measurementNode =
- reader.readMetadataIndexNode(
- startEndPair.right[0], startEndPair.right[1], false,
ioSizeRecorder);
- boolean isAligned = reader.isAlignedDevice(measurementNode);
- currentDevice = new Pair<>(startEndPair.left, isAligned);
- return currentDevice;
+ return new Pair<>(deviceId,
lazyTsFileDeviceIterator.isCurrentDeviceAligned());
} catch (IOException e) {
throw new TsFileRuntimeException(
"Error occurred while reading a time series metadata block.");
}
}
- public MetadataIndexNode getFirstMeasurementNodeOfCurrentDevice() {
- return measurementNode;
+ public MetadataIndexNode getFirstMeasurementNodeOfCurrentDevice() throws
IOException {
+ return lazyTsFileDeviceIterator.getFirstMeasurementNodeOfCurrentDevice();
}
- /**
- * Get devices and first measurement node offset.
- *
- * @param startOffset start offset of device leaf node
- * @param endOffset end offset of device leaf node
- * @param measurementNodeOffsetQueue device -> first measurement node offset
- */
- public void getDevicesAndEntriesOfOneLeafNode(
- Long startOffset, Long endOffset, Queue<Pair<IDeviceID, long[]>>
measurementNodeOffsetQueue)
- throws IOException {
- try {
- ByteBuffer nextBuffer = reader.readData(startOffset, endOffset,
ioSizeRecorder);
- MetadataIndexNode deviceLeafNode =
-
deserializeConfig.deviceMetadataIndexNodeBufferDeserializer.deserialize(
- nextBuffer, deserializeConfig);
- getDevicesOfLeafNode(deviceLeafNode, measurementNodeOffsetQueue);
- } catch (StopReadTsFileByInterruptException e) {
- throw e;
- } catch (Exception e) {
- logger.error(
- "Something error happened while getting all devices of file {}",
reader.getFileName());
- throw e;
- }
- }
-
- /**
- * Get all devices and its corresponding entries on the specific device leaf
node.
- *
- * @param deviceLeafNode this node must be device leaf node
- */
- private void getDevicesOfLeafNode(
- MetadataIndexNode deviceLeafNode, Queue<Pair<IDeviceID, long[]>>
measurementNodeOffsetQueue) {
- if
(!deviceLeafNode.getNodeType().equals(MetadataIndexNodeType.LEAF_DEVICE)) {
- throw new IllegalStateException("the first param should be device leaf
node.");
- }
- List<IMetadataIndexEntry> childrenEntries = deviceLeafNode.getChildren();
- for (int i = 0; i < childrenEntries.size(); i++) {
- IMetadataIndexEntry deviceEntry = childrenEntries.get(i);
- long childStartOffset = deviceEntry.getOffset();
- long childEndOffset =
- i == childrenEntries.size() - 1
- ? deviceLeafNode.getEndOffset()
- : childrenEntries.get(i + 1).getOffset();
- long[] offset = {childStartOffset, childEndOffset};
- measurementNodeOffsetQueue.add(
- new Pair<>(((DeviceMetadataIndexEntry) deviceEntry).getDeviceID(),
offset));
- }
- }
-
- /**
- * Get the device leaf node offset under the specific device internal node.
- *
- * @param deviceInternalNode this node must be device internal node
- */
- private void getAllDeviceLeafNodeOffset(
- MetadataIndexNode deviceInternalNode, List<long[]>
leafDeviceNodeOffsets) throws IOException {
- if
(!deviceInternalNode.getNodeType().equals(MetadataIndexNodeType.INTERNAL_DEVICE))
{
- throw new IllegalStateException("the first param should be device
internal node.");
- }
- try {
- int metadataIndexListSize = deviceInternalNode.getChildren().size();
- boolean isCurrentLayerLeafNode = false;
- for (int i = 0; i < metadataIndexListSize; i++) {
- IMetadataIndexEntry entry = deviceInternalNode.getChildren().get(i);
- long startOffset = entry.getOffset();
- long endOffset = deviceInternalNode.getEndOffset();
- if (i != metadataIndexListSize - 1) {
- endOffset = deviceInternalNode.getChildren().get(i + 1).getOffset();
- }
- if (i == 0) {
- // check is current layer device leaf node or device internal node.
Just need to check the
- // first entry, because the rest are the same
- MetadataIndexNodeType nodeType =
- MetadataIndexNodeType.deserialize(
- ReadWriteIOUtils.readByte(
- reader.readData(endOffset - 1, endOffset,
ioSizeRecorder)));
- isCurrentLayerLeafNode =
nodeType.equals(MetadataIndexNodeType.LEAF_DEVICE);
- }
- if (isCurrentLayerLeafNode) {
- // is device leaf node
- long[] offset = {startOffset, endOffset};
- leafDeviceNodeOffsets.add(offset);
- continue;
- }
- ByteBuffer nextBuffer = reader.readData(startOffset, endOffset,
ioSizeRecorder);
- getAllDeviceLeafNodeOffset(
-
deserializeConfig.deviceMetadataIndexNodeBufferDeserializer.deserialize(
- nextBuffer, deserializeConfig),
- leafDeviceNodeOffsets);
- }
- } catch (StopReadTsFileByInterruptException e) {
- throw e;
- } catch (Exception e) {
- logger.error(
- "Something error happened while getting all devices of file {}",
reader.getFileName());
- throw e;
- }
+ public long[] getCurrentDeviceMeasurementNodeOffset() {
+ return lazyTsFileDeviceIterator.getCurrentDeviceMeasurementNodeOffset();
}
}
diff --git
a/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileSequenceReader.java
b/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileSequenceReader.java
index 132c6f34..35a39dc9 100644
--- a/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileSequenceReader.java
+++ b/java/tsfile/src/main/java/org/apache/tsfile/read/TsFileSequenceReader.java
@@ -1118,12 +1118,17 @@ public class TsFileSequenceReader implements
AutoCloseable {
/**
* @return an iterator of "device, isAligned" list, in which names of
devices are ordered in
* dictionary order, and isAligned represents whether the device is
aligned. Only read devices
- * on one device leaf node each time to save memory.
+ * on one device leaf node each time to save memory. If you only need to
iterate through the
+ * device and don't need to know if the device is aligned, use
LazyTsFileDeviceIterator.
*/
public TsFileDeviceIterator getAllDevicesIteratorWithIsAligned() throws
IOException {
return new TsFileDeviceIterator(this);
}
+ public LazyTsFileDeviceIterator getLazyDeviceIterator() throws IOException {
+ return new LazyTsFileDeviceIterator(this);
+ }
+
public TsFileDeviceIterator getTableDevicesIteratorWithIsAligned(
String tableName, LongConsumer ioSizeRecorder) throws IOException {
return new TsFileDeviceIterator(this, tableName, ioSizeRecorder);
diff --git
a/java/tsfile/src/test/java/org/apache/tsfile/read/TsFileDeviceIteratorTest.java
b/java/tsfile/src/test/java/org/apache/tsfile/read/TsFileDeviceIteratorTest.java
index 5dd1a096..5e73ed82 100644
---
a/java/tsfile/src/test/java/org/apache/tsfile/read/TsFileDeviceIteratorTest.java
+++
b/java/tsfile/src/test/java/org/apache/tsfile/read/TsFileDeviceIteratorTest.java
@@ -82,8 +82,21 @@ public class TsFileDeviceIteratorTest {
}
previous = next.getLeft();
}
+ Assert.assertEquals(totalDeviceNum, deviceFromIterator);
+
+ deviceFromIterator = 0;
+ deviceIterator = reader.getTableDevicesIteratorWithIsAligned("table2",
null);
+ previous = null;
+ while (deviceIterator.hasNext()) {
+ Pair<IDeviceID, Boolean> next = deviceIterator.next();
+ deviceFromIterator++;
+ if (previous != null) {
+ Assert.assertTrue(previous.compareTo(next.getLeft()) < 0);
+ }
+ previous = next.getLeft();
+ }
+ Assert.assertEquals(20000, deviceFromIterator);
}
- Assert.assertEquals(totalDeviceNum, deviceFromIterator);
}
private void registerTableSchema(TsFileIOWriter writer, String tableName) {