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

gongxun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git


The following commit(s) were added to refs/heads/main by this push:
     new 5ad83d33af1 Enhancement: simple code optimization
5ad83d33af1 is described below

commit 5ad83d33af19a3730fe192248284d65552e64f97
Author: GongXun <[email protected]>
AuthorDate: Sun Sep 21 21:17:22 2025 +0800

    Enhancement: simple code optimization
    
    1. Explicit inline functions.
    2. Instead of checking the physical size of the file every time a tuple
    is inserted, it is checked every 16 tuples.
    
    performance result
    ```
    create table t1(a int, b int, c int, d int, e text, f text,g text, h text) 
using pax with(compresstype
    =zstd,compresslevel=5);
    
    gpadmin=# insert into t1 select i, i+1,i+2,i+3, i::text, i::text, i::text, 
i::text from generate_series(1,5000000) i;
    INSERT 0 5000000
    Time: 6124.535 ms (00:06.125)
    gpadmin=# insert into t1 select i, i+1,i+2,i+3, i::text, i::text, i::text, 
i::text from generate_series(1,5000000) i;
    INSERT 0 5000000
    Time: 5993.682 ms (00:05.994)
    
    -- optimized with this commit
    create table t1(a int, b int, c int, d int, e text, f text,g text, h text) 
using pax with(compresstype
    =zstd,compresslevel=5);
    gpadmin=# insert into t1 select i, i+1,i+2,i+3, i::text, i::text, i::text, 
i::text from generate_series(1,5000000) i;
    INSERT 0 5000000
    Time: 5713.184 ms (00:05.713)
    gpadmin=# insert into t1 select i, i+1,i+2,i+3, i::text, i::text, i::text, 
i::text from generate_series(1,5000000) i;
    INSERT 0 5000000
    Time: 5430.221 ms (00:05.430)
    
    ```
---
 .../pax_storage/src/cpp/access/pax_dml_state.cc    |  4 +--
 contrib/pax_storage/src/cpp/comm/cbdb_wrappers.cc  |  6 ----
 contrib/pax_storage/src/cpp/comm/cbdb_wrappers.h   |  6 ++--
 .../pax_storage/src/cpp/storage/orc/orc_writer.cc  |  6 +++-
 contrib/pax_storage/src/cpp/storage/pax.cc         | 19 ++++++++++--
 contrib/pax_storage/src/cpp/storage/pax.h          |  1 +
 .../src/cpp/storage/vec/pax_porc_adpater.cc        | 36 +++++++++++++++++++---
 7 files changed, 60 insertions(+), 18 deletions(-)

diff --git a/contrib/pax_storage/src/cpp/access/pax_dml_state.cc 
b/contrib/pax_storage/src/cpp/access/pax_dml_state.cc
index 0a7d367d34f..40cb6bdcdcd 100644
--- a/contrib/pax_storage/src/cpp/access/pax_dml_state.cc
+++ b/contrib/pax_storage/src/cpp/access/pax_dml_state.cc
@@ -104,7 +104,7 @@ void CPaxDmlStateLocal::Reset() { cbdb::pax_memory_context 
= nullptr; }
 CPaxDmlStateLocal::CPaxDmlStateLocal()
     : last_oid_(InvalidOid), cb_{.func = DmlStateResetCallback, .arg = NULL} {}
 
-std::shared_ptr<CPaxDmlStateLocal::DmlStateValue>
+pg_attribute_always_inline std::shared_ptr<CPaxDmlStateLocal::DmlStateValue>
 CPaxDmlStateLocal::RemoveDmlState(const Oid &oid) {
   std::shared_ptr<CPaxDmlStateLocal::DmlStateValue> value;
 
@@ -121,7 +121,7 @@ CPaxDmlStateLocal::RemoveDmlState(const Oid &oid) {
   return value;
 }
 
-std::shared_ptr<CPaxDmlStateLocal::DmlStateValue>
+pg_attribute_always_inline std::shared_ptr<CPaxDmlStateLocal::DmlStateValue>
 CPaxDmlStateLocal::FindDmlState(const Oid &oid) {
   Assert(OidIsValid(oid));
 
diff --git a/contrib/pax_storage/src/cpp/comm/cbdb_wrappers.cc 
b/contrib/pax_storage/src/cpp/comm/cbdb_wrappers.cc
index b9d1a723028..3e54e965698 100644
--- a/contrib/pax_storage/src/cpp/comm/cbdb_wrappers.cc
+++ b/contrib/pax_storage/src/cpp/comm/cbdb_wrappers.cc
@@ -124,12 +124,6 @@ void cbdb::MemoryCtxRegisterResetCallback(MemoryContext 
context,
   CBDB_WRAP_END;
 }
 
-Oid cbdb::RelationGetRelationId(Relation rel) {
-  CBDB_WRAP_START;
-  { return RelationGetRelid(rel); }
-  CBDB_WRAP_END;
-}
-
 #ifdef RUN_GTEST
 Datum cbdb::DatumFromCString(const char *src, size_t length) {
   CBDB_WRAP_START;
diff --git a/contrib/pax_storage/src/cpp/comm/cbdb_wrappers.h 
b/contrib/pax_storage/src/cpp/comm/cbdb_wrappers.h
index 05738a4b2ab..2031662357d 100644
--- a/contrib/pax_storage/src/cpp/comm/cbdb_wrappers.h
+++ b/contrib/pax_storage/src/cpp/comm/cbdb_wrappers.h
@@ -114,8 +114,6 @@ void MemoryCtxDelete(MemoryContext memory_context);
 void MemoryCtxRegisterResetCallback(MemoryContext context,
                                     MemoryContextCallback *cb);
 
-Oid RelationGetRelationId(Relation rel);
-
 static inline void *DatumToPointer(Datum d) noexcept {
   return DatumGetPointer(d);
 }
@@ -164,6 +162,10 @@ static inline float8 DatumToFloat8(Datum d) noexcept {
   return DatumGetFloat8(d);
 }
 
+static pg_attribute_always_inline Oid RelationGetRelationId(Relation rel) 
noexcept {
+  return RelationGetRelid(rel);
+}
+
 BpChar *BpcharInput(const char *s, size_t len, int32 atttypmod);
 VarChar *VarcharInput(const char *s, size_t len, int32 atttypmod);
 text *CstringToText(const char *s, size_t len);
diff --git a/contrib/pax_storage/src/cpp/storage/orc/orc_writer.cc 
b/contrib/pax_storage/src/cpp/storage/orc/orc_writer.cc
index 5c8b52272d0..a33d2de0fc1 100644
--- a/contrib/pax_storage/src/cpp/storage/orc/orc_writer.cc
+++ b/contrib/pax_storage/src/cpp/storage/orc/orc_writer.cc
@@ -367,7 +367,11 @@ std::vector<std::pair<int, Datum>> 
OrcWriter::PrepareWriteTuple(
     // Numeric always need ensure that with the 4B header, otherwise it will
     // be converted twice in the vectorization path.
     if (required_stats_cols[i] || VARATT_IS_COMPRESSED(tts_value_vl) ||
-        VARATT_IS_EXTERNAL(tts_value_vl) || attrs->atttypid == NUMERICOID) {
+        VARATT_IS_EXTERNAL(tts_value_vl)
+#ifdef VEC_BUILD
+        || attrs->atttypid == NUMERICOID
+#endif
+    ) {
       // still detoast the origin toast
       detoast_vl = cbdb::PgDeToastDatum(tts_value_vl);
       Assert(detoast_vl != nullptr);
diff --git a/contrib/pax_storage/src/cpp/storage/pax.cc 
b/contrib/pax_storage/src/cpp/storage/pax.cc
index c8d29bbb6ce..69282738f4c 100644
--- a/contrib/pax_storage/src/cpp/storage/pax.cc
+++ b/contrib/pax_storage/src/cpp/storage/pax.cc
@@ -49,6 +49,8 @@
 #include "storage/vec/pax_vec_reader.h"
 #endif
 
+#define PAX_SPLIT_STRATEGY_CHECK_INTERVAL (16)
+
 namespace paxc {
 class IndexUpdaterInternal {
  public:
@@ -280,14 +282,25 @@ void TableWriter::Open() {
   // insert tuple into the aux table before inserting any tuples.
   cbdb::InsertMicroPartitionPlaceHolder(RelationGetRelid(relation_),
                                         current_blockno_);
+  cur_physical_size_ = 0;
 }
 
 void TableWriter::WriteTuple(TupleTableSlot *slot) {
   Assert(writer_);
   Assert(strategy_);
-  // should check split strategy before write tuple
-  // otherwise, may got a empty file in the disk
-  if (strategy_->ShouldSplit(writer_->PhysicalSize(), num_tuples_)) {
+  // Because of the CTID constraint, we have to strictly enforce the accuracy 
of
+  // the tuple count and make sure it doesn't exceed
+  // PAX_MAX_NUM_TUPLES_PER_FILE. That's why we kept this precise check here.
+
+  // On the other hand,the biggest performance hit here is the PhysicalSize()
+  // function.So to reduce the overhead of calling it so often,
+  // we only update the file size every PAX_SPLIT_STRATEGY_CHECK_INTERVAL
+  // tuples.
+  if ((num_tuples_ % PAX_SPLIT_STRATEGY_CHECK_INTERVAL) == 0) {
+    cur_physical_size_ = writer_->PhysicalSize();
+  }
+
+  if (strategy_->ShouldSplit(cur_physical_size_, num_tuples_)) {
     writer_->Close();
     writer_ = nullptr;
     Open();
diff --git a/contrib/pax_storage/src/cpp/storage/pax.h 
b/contrib/pax_storage/src/cpp/storage/pax.h
index 1d7a2f6b3fc..fec97e613f3 100644
--- a/contrib/pax_storage/src/cpp/storage/pax.h
+++ b/contrib/pax_storage/src/cpp/storage/pax.h
@@ -131,6 +131,7 @@ class TableWriter {
   std::vector<std::tuple<ColumnEncoding_Kind, int>> encoding_opts_;
 
   bool is_dfs_table_space_;
+  size_t cur_physical_size_ = 0;
 };
 
 class TableReader final {
diff --git a/contrib/pax_storage/src/cpp/storage/vec/pax_porc_adpater.cc 
b/contrib/pax_storage/src/cpp/storage/vec/pax_porc_adpater.cc
index 65eeb4e88ae..7545e053b6e 100644
--- a/contrib/pax_storage/src/cpp/storage/vec/pax_porc_adpater.cc
+++ b/contrib/pax_storage/src/cpp/storage/vec/pax_porc_adpater.cc
@@ -29,6 +29,8 @@
 
 #ifdef VEC_BUILD
 
+#include <stdlib.h>
+
 #include "comm/vec_numeric.h"
 #include "storage/columns/pax_column_traits.h"
 #include "storage/toast/pax_toast.h"
@@ -38,6 +40,22 @@
 #endif
 namespace pax {
 
+static inline struct varlena *VarlenaShortTo4B(struct varlena *attr) {
+  Assert(attr != nullptr);
+  Assert(VARATT_IS_SHORT(attr));
+  Size data_size = VARSIZE_SHORT(attr) - VARHDRSZ_SHORT;
+  Size new_size = data_size + VARHDRSZ;
+
+  struct varlena *new_attr =
+      reinterpret_cast<struct varlena *>(malloc(new_size));
+
+  Assert(new_attr != nullptr);
+
+  SET_VARSIZE(new_attr, new_size);
+  memcpy(VARDATA(new_attr), VARDATA_SHORT(attr), data_size);
+  return new_attr;
+}
+
 static void CopyFixedRawBufferWithNull(
     PaxColumn *column, std::shared_ptr<Bitmap8> visibility_map_bitset,
     size_t bitset_index_begin, size_t range_begin, size_t range_lens,
@@ -235,16 +253,22 @@ static void CopyDecimalBuffer(PaxColumn *column,
       out_data_buffer->Brush(type_len);
     } else {
       Numeric numeric;
+      bool should_free = false;
       size_t num_len = 0;
       std::tie(buffer, buffer_len) =
           column->GetBuffer(data_index_begin + non_null_offset);
 
       auto vl = (struct varlena *)DatumGetPointer(buffer);
-      Assert(!(VARATT_IS_EXTERNAL(vl) || VARATT_IS_COMPRESSED(vl) ||
-               VARATT_IS_SHORT(vl)));
+      Assert(!(VARATT_IS_EXTERNAL(vl) || VARATT_IS_COMPRESSED(vl)));
       num_len = VARSIZE_ANY_EXHDR(vl);
-      // direct cast
-      numeric = (Numeric)(buffer);
+      // it has been detoasted in OrcWriter::PrepareWriteTuple, except numeric
+      // type with short header should be detoasted to 4B header
+      if (unlikely(VARATT_IS_SHORT(vl))) {
+        numeric = VarlenaShortTo4B(vl);
+        should_free = true;
+      } else {  // direct cast
+        numeric = (Numeric)(buffer);
+      }
 
       char *dest_buff = out_data_buffer->GetAvailableBuffer();
       Assert(out_data_buffer->Available() >= (size_t)type_len);
@@ -253,6 +277,10 @@ static void CopyDecimalBuffer(PaxColumn *column,
           (int64 *)(dest_buff + sizeof(int64)));
       out_data_buffer->Brush(type_len);
       non_null_offset++;
+
+      if (should_free) {
+        free(numeric);
+      }
     }
   }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to