This is an automated email from the ASF dual-hosted git repository.

jiangtian pushed a commit to branch deviceId_with_null
in repository https://gitbox.apache.org/repos/asf/tsfile.git

commit 39f6730d8c5d725fff05b33ab0922d234c14410c
Author: Tian Jiang <[email protected]>
AuthorDate: Wed Jul 31 09:43:16 2024 +0800

    add processing when a deviceId contains null
---
 .../tsfile/exception/IllegalDeviceIDException.java | 27 ++++++++++++++++++++
 .../tsfile/file/metadata/StringArrayDeviceID.java  | 29 +++++++++++++++++++++-
 .../apache/tsfile/file/metadata/IDeviceIDTest.java | 29 ++++++++++++++++++++++
 3 files changed, 84 insertions(+), 1 deletion(-)

diff --git 
a/java/tsfile/src/main/java/org/apache/tsfile/exception/IllegalDeviceIDException.java
 
b/java/tsfile/src/main/java/org/apache/tsfile/exception/IllegalDeviceIDException.java
new file mode 100644
index 00000000..400d655d
--- /dev/null
+++ 
b/java/tsfile/src/main/java/org/apache/tsfile/exception/IllegalDeviceIDException.java
@@ -0,0 +1,27 @@
+/*
+ * 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.exception;
+
+public class IllegalDeviceIDException extends RuntimeException {
+
+  public IllegalDeviceIDException(String message) {
+    super(message);
+  }
+}
diff --git 
a/java/tsfile/src/main/java/org/apache/tsfile/file/metadata/StringArrayDeviceID.java
 
b/java/tsfile/src/main/java/org/apache/tsfile/file/metadata/StringArrayDeviceID.java
index 2001566b..319b3ae2 100644
--- 
a/java/tsfile/src/main/java/org/apache/tsfile/file/metadata/StringArrayDeviceID.java
+++ 
b/java/tsfile/src/main/java/org/apache/tsfile/file/metadata/StringArrayDeviceID.java
@@ -20,6 +20,7 @@
 package org.apache.tsfile.file.metadata;
 
 import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.exception.IllegalDeviceIDException;
 import org.apache.tsfile.exception.TsFileRuntimeException;
 import org.apache.tsfile.read.common.parser.PathNodesGenerator;
 import org.apache.tsfile.utils.RamUsageEstimator;
@@ -76,13 +77,39 @@ public class StringArrayDeviceID implements IDeviceID {
   private final String[] segments;
 
   public StringArrayDeviceID(String... segments) {
-    this.segments = segments;
+    this.segments = formalize(segments);
   }
 
   public StringArrayDeviceID(String deviceIdString) {
     this.segments = splitDeviceIdString(deviceIdString);
   }
 
+  private String[] formalize(String[] segments) {
+    // remove tailing nulls
+    int i = segments.length - 1;
+    for (; i >= 0; i--) {
+      if (segments[i] != null) {
+        break;
+      }
+    }
+    if (i < 0) {
+      throw new IllegalDeviceIDException("All segments are null");
+    }
+    if (i == 0) {
+      // for a deviceId that only contains the table name, add a tailing null 
so that we can
+      // create the associated device metadata node
+      if (segments.length > 1) {
+        segments = Arrays.copyOf(segments, 2);
+      } else {
+        // segments.length == 1
+        segments = new String[] {segments[0], null};
+      }
+    } else if (i != segments.length - 1) {
+      segments = Arrays.copyOf(segments, i + 1);
+    }
+    return segments;
+  }
+
   @SuppressWarnings("java:S125") // confusing comments with codes
   private static String[] splitDeviceIdString(String deviceIdString) {
     List<String> splits = 
Arrays.asList(PathNodesGenerator.splitPathToNodes(deviceIdString));
diff --git 
a/java/tsfile/src/test/java/org/apache/tsfile/file/metadata/IDeviceIDTest.java 
b/java/tsfile/src/test/java/org/apache/tsfile/file/metadata/IDeviceIDTest.java
index 6490eef4..05c2dbf6 100644
--- 
a/java/tsfile/src/test/java/org/apache/tsfile/file/metadata/IDeviceIDTest.java
+++ 
b/java/tsfile/src/test/java/org/apache/tsfile/file/metadata/IDeviceIDTest.java
@@ -19,6 +19,7 @@
 
 package org.apache.tsfile.file.metadata;
 
+import org.apache.tsfile.exception.IllegalDeviceIDException;
 import org.apache.tsfile.file.metadata.IDeviceID.Deserializer;
 import org.apache.tsfile.file.metadata.IDeviceID.Factory;
 
@@ -30,6 +31,8 @@ import java.nio.ByteBuffer;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 
 public class IDeviceIDTest {
@@ -88,6 +91,32 @@ public class IDeviceIDTest {
     assertFalse(deviceID.matchDatabaseName("root.a"));
   }
 
+  @Test
+  public void testWithNull() {
+    // auto adding tailing null for one segment id
+    IDeviceID deviceID = Factory.DEFAULT_FACTORY.create(new String[] 
{"table1"});
+    assertEquals(2, deviceID.segmentNum());
+    assertEquals("table1", deviceID.segment(0));
+    assertNull(deviceID.segment(1));
+
+    // removing tailing null
+    deviceID = Factory.DEFAULT_FACTORY.create(new String[] {"table1", "a", 
null, null});
+    assertEquals(2, deviceID.segmentNum());
+    assertEquals("table1", deviceID.segment(0));
+    assertEquals("a", deviceID.segment(1));
+
+    // removing tailing null but leaving the last null
+    deviceID = Factory.DEFAULT_FACTORY.create(new String[] {"table1", null, 
null, null});
+    assertEquals(2, deviceID.segmentNum());
+    assertEquals("table1", deviceID.segment(0));
+    assertNull(deviceID.segment(1));
+
+    // all null
+    assertThrows(
+        IllegalDeviceIDException.class,
+        () -> Factory.DEFAULT_FACTORY.create(new String[] {null, null, null, 
null}));
+  }
+
   @Test
   public void testSerialize() throws IOException {
     testSerialize(Factory.DEFAULT_FACTORY.create("root"));

Reply via email to