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

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


The following commit(s) were added to refs/heads/develop by this push:
     new be7bd7e5 Added memory calculation for tablet (#636)
be7bd7e5 is described below

commit be7bd7e56c4c609f529dd8b396bd0d52213c594f
Author: Caideyipi <[email protected]>
AuthorDate: Thu Nov 13 11:15:43 2025 +0800

    Added memory calculation for tablet (#636)
    
    * fx
    
    * fix
    
    * dl
---
 .../org/apache/tsfile/utils/RamUsageEstimator.java | 76 ++++++++++++++++++
 .../org/apache/tsfile/write/record/Tablet.java     | 89 +++++++++++++++++++---
 2 files changed, 154 insertions(+), 11 deletions(-)

diff --git 
a/java/common/src/main/java/org/apache/tsfile/utils/RamUsageEstimator.java 
b/java/common/src/main/java/org/apache/tsfile/utils/RamUsageEstimator.java
index af7a8cff..29b9d085 100644
--- a/java/common/src/main/java/org/apache/tsfile/utils/RamUsageEstimator.java
+++ b/java/common/src/main/java/org/apache/tsfile/utils/RamUsageEstimator.java
@@ -27,6 +27,7 @@ import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
+import java.time.LocalDate;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -35,6 +36,7 @@ import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -99,6 +101,11 @@ public final class RamUsageEstimator {
   /** Sizes of primitive classes. */
   public static final Map<Class<?>, Integer> primitiveSizes;
 
+  public static final long LOCAL_DATE_ARRAY_SIZE;
+  public static final long LOCAL_DATE_SIZE;
+  public static final long BIT_MAP_SIZE;
+  public static final long SIZE_OF_ARRAYLIST;
+
   static {
     Map<Class<?>, Integer> primitiveSizesMap = new IdentityHashMap<>();
     primitiveSizesMap.put(boolean.class, 1);
@@ -111,6 +118,11 @@ public final class RamUsageEstimator {
     primitiveSizesMap.put(long.class, Long.BYTES);
 
     primitiveSizes = Collections.unmodifiableMap(primitiveSizesMap);
+
+    LOCAL_DATE_ARRAY_SIZE = RamUsageEstimator.shallowSizeOf(LocalDate[].class);
+    LOCAL_DATE_SIZE = RamUsageEstimator.shallowSizeOf(LocalDate.class);
+    BIT_MAP_SIZE = RamUsageEstimator.shallowSizeOfInstance(BitMap.class);
+    SIZE_OF_ARRAYLIST = 
RamUsageEstimator.shallowSizeOfInstance(ArrayList.class);
   }
 
   /** JVMs typically cache small longs. This tries to find out what the range 
is. */
@@ -654,4 +666,68 @@ public final class RamUsageEstimator {
   public static long sizeOfObjectArray(int length) {
     return alignObjectSize(NUM_BYTES_ARRAY_HEADER + (long) 
NUM_BYTES_OBJECT_REF * length);
   }
+
+  private static long sizeOf(final Binary binary) {
+    return Objects.nonNull(binary) ? binary.ramBytesUsed() : 0L;
+  }
+
+  public static long sizeOf(final Binary[] binaries) {
+    if (binaries == null) {
+      return 0L;
+    }
+
+    long size = 0L;
+    for (Binary binary : binaries) {
+      size += sizeOf(binary);
+    }
+
+    return size + RamUsageEstimator.shallowSizeOf(binaries);
+  }
+
+  public static long sizeOfStringArray(final String[] values) {
+    return Objects.nonNull(values) ? RamUsageEstimator.sizeOf(values) : 0L;
+  }
+
+  public static long sizeOf(BitMap[] bitMaps) {
+    if (bitMaps == null) {
+      return 0L;
+    }
+    long size =
+        RamUsageEstimator.alignObjectSize(
+            NUM_BYTES_ARRAY_HEADER + (long) NUM_BYTES_OBJECT_REF * 
bitMaps.length);
+    for (BitMap bitMap : bitMaps) {
+      size += sizeOf(bitMap);
+    }
+    return size;
+  }
+
+  private static long sizeOf(final BitMap bitMap) {
+    if (bitMap == null) {
+      return 0L;
+    }
+    long size = BIT_MAP_SIZE;
+
+    size +=
+        RamUsageEstimator.alignObjectSize(NUM_BYTES_ARRAY_HEADER + 
bitMap.getByteArray().length);
+    return size;
+  }
+
+  public static long sizeOf(final LocalDate[] input) {
+    if (Objects.isNull(input)) {
+      return 0;
+    }
+    long size =
+        RamUsageEstimator.alignObjectSize(
+            LOCAL_DATE_ARRAY_SIZE + (long) input.length * 
NUM_BYTES_OBJECT_REF);
+    for (final LocalDate date : input) {
+      if (Objects.nonNull(date)) {
+        size += LOCAL_DATE_SIZE;
+      }
+    }
+    return size;
+  }
+
+  public static long shallowSizeOfList(final List<?> input) {
+    return alignObjectSize(SIZE_OF_ARRAYLIST + (long) input.size() * 
NUM_BYTES_OBJECT_REF);
+  }
 }
diff --git 
a/java/tsfile/src/main/java/org/apache/tsfile/write/record/Tablet.java 
b/java/tsfile/src/main/java/org/apache/tsfile/write/record/Tablet.java
index 8336d2b7..89b6f2a6 100644
--- a/java/tsfile/src/main/java/org/apache/tsfile/write/record/Tablet.java
+++ b/java/tsfile/src/main/java/org/apache/tsfile/write/record/Tablet.java
@@ -27,11 +27,13 @@ import org.apache.tsfile.enums.ColumnCategory;
 import org.apache.tsfile.enums.TSDataType;
 import org.apache.tsfile.file.metadata.IDeviceID;
 import org.apache.tsfile.file.metadata.StringArrayDeviceID;
+import org.apache.tsfile.utils.Accountable;
 import org.apache.tsfile.utils.Binary;
 import org.apache.tsfile.utils.BitMap;
 import org.apache.tsfile.utils.BytesUtils;
 import org.apache.tsfile.utils.DateUtils;
 import org.apache.tsfile.utils.PublicBAOS;
+import org.apache.tsfile.utils.RamUsageEstimator;
 import org.apache.tsfile.utils.ReadWriteIOUtils;
 import org.apache.tsfile.write.UnSupportedDataTypeException;
 import org.apache.tsfile.write.schema.IMeasurementSchema;
@@ -48,6 +50,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 
+import static org.apache.tsfile.utils.RamUsageEstimator.shallowSizeOfList;
+
 /**
  * A tablet data of one device, the tablet contains multiple measurements of 
this device that share
  * the same time column.
@@ -59,8 +63,8 @@ import java.util.Objects;
  * <p>Notice: The tablet should not have empty cell, please use BitMap to 
denote null value
  */
 @SuppressWarnings("SuspiciousSystemArraycopy")
-public class Tablet {
-
+public class Tablet implements Accountable {
+  private static final long TABLET_SIZE = 
RamUsageEstimator.shallowSizeOfInstance(Tablet.class);
   private static final int DEFAULT_SIZE = 1024;
   private static final String NOT_SUPPORT_DATATYPE = "Data type %s is not 
supported.";
   private static final LocalDate EMPTY_DATE = LocalDate.of(1000, 1, 1);
@@ -78,7 +82,7 @@ public class Tablet {
   private List<ColumnCategory> columnCategories;
 
   /** Columns in the list are all ID columns. */
-  private List<Integer> idColumnIndexes = new ArrayList<>();
+  private final List<Integer> tagColumnIndexes = new ArrayList<>();
 
   /** MeasurementId->indexOf({@link MeasurementSchema}) */
   private final Map<String, Integer> measurementIndex;
@@ -869,8 +873,7 @@ public class Tablet {
     Object[] values = new Object[schemaSize];
     boolean isValuesNotNull = 
BytesUtils.byteToBool(ReadWriteIOUtils.readByte(byteBuffer));
     if (isValuesNotNull) {
-      values =
-          readTabletValuesFromBuffer(byteBuffer, dataTypes, columnCategories, 
schemaSize, rowSize);
+      values = readvaluesFromBuffer(byteBuffer, dataTypes, columnCategories, 
schemaSize, rowSize);
     }
 
     Tablet tablet =
@@ -899,7 +902,7 @@ public class Tablet {
    * @param columns column number
    */
   @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity 
warning
-  public static Object[] readTabletValuesFromBuffer(
+  public static Object[] readvaluesFromBuffer(
       ByteBuffer byteBuffer,
       TSDataType[] types,
       List<ColumnCategory> columnCategories,
@@ -1237,10 +1240,10 @@ public class Tablet {
    */
   @TableModel
   public IDeviceID getDeviceID(int i) {
-    String[] idArray = new String[idColumnIndexes.size() + 1];
+    String[] idArray = new String[tagColumnIndexes.size() + 1];
     idArray[0] = getTableName();
-    for (int j = 0; j < idColumnIndexes.size(); j++) {
-      final Object value = getValue(i, idColumnIndexes.get(j));
+    for (int j = 0; j < tagColumnIndexes.size(); j++) {
+      final Object value = getValue(i, tagColumnIndexes.get(j));
       idArray[j + 1] = value != null ? value.toString() : null;
     }
     return new StringArrayDeviceID(idArray);
@@ -1248,11 +1251,11 @@ public class Tablet {
 
   public void setColumnCategories(List<ColumnCategory> columnCategories) {
     this.columnCategories = columnCategories;
-    idColumnIndexes.clear();
+    tagColumnIndexes.clear();
     for (int i = 0; i < columnCategories.size(); i++) {
       ColumnCategory columnCategory = columnCategories.get(i);
       if (columnCategory.equals(ColumnCategory.TAG)) {
-        idColumnIndexes.add(i);
+        tagColumnIndexes.add(i);
       }
     }
   }
@@ -1493,4 +1496,68 @@ public class Tablet {
       }
     }
   }
+
+  @Override
+  public long ramBytesUsed() {
+    long totalSizeInBytes =
+        TABLET_SIZE
+            + RamUsageEstimator.sizeOf(insertTargetName)
+            + RamUsageEstimator.sizeOf(timestamps)
+            + shallowSizeOfList(columnCategories)
+            + RamUsageEstimator.sizeOf(bitMaps)
+            + RamUsageEstimator.shallowSizeOfList(tagColumnIndexes)
+            + RamUsageEstimator.sizeOfMap(measurementIndex);
+
+    // values
+    final List<IMeasurementSchema> timeSeries = schemas;
+
+    if (timeSeries != null) {
+      totalSizeInBytes += RamUsageEstimator.shallowSizeOfList(timeSeries);
+      for (int column = 0; column < timeSeries.size(); column++) {
+        final IMeasurementSchema measurementSchema = timeSeries.get(column);
+        if (measurementSchema == null) {
+          continue;
+        }
+        // Measurement schema size
+        totalSizeInBytes += 75;
+
+        final TSDataType tsDataType = measurementSchema.getType();
+        if (tsDataType == null) {
+          continue;
+        }
+
+        if (values == null || values.length <= column) {
+          continue;
+        }
+        switch (tsDataType) {
+          case INT64:
+          case TIMESTAMP:
+            totalSizeInBytes += RamUsageEstimator.sizeOf((long[]) 
values[column]);
+            break;
+          case DATE:
+            totalSizeInBytes += RamUsageEstimator.sizeOf((LocalDate[]) 
values[column]);
+            break;
+          case INT32:
+            totalSizeInBytes += RamUsageEstimator.sizeOf((int[]) 
values[column]);
+            break;
+          case DOUBLE:
+            totalSizeInBytes += RamUsageEstimator.sizeOf((double[]) 
values[column]);
+            break;
+          case FLOAT:
+            totalSizeInBytes += RamUsageEstimator.sizeOf((float[]) 
values[column]);
+            break;
+          case BOOLEAN:
+            totalSizeInBytes += RamUsageEstimator.sizeOf((boolean[]) 
values[column]);
+            break;
+          case STRING:
+          case TEXT:
+          case BLOB:
+            totalSizeInBytes += RamUsageEstimator.sizeOf((Binary[]) 
values[column]);
+            break;
+        }
+      }
+    }
+
+    return totalSizeInBytes;
+  }
 }

Reply via email to