fix: to_cstring may use lot of time and memory

This commit is contained in:
obdev
2023-09-15 14:10:12 +00:00
committed by ob-robot
parent 47089d3931
commit 0dbddf0b27
2 changed files with 33 additions and 30 deletions

View File

@ -151,16 +151,18 @@ public:
static const int MIN_SIZE = 12 * 1024; static const int MIN_SIZE = 12 * 1024;
struct BufNode struct BufNode
{ {
char buf_[MIN_SIZE]; BufNode() : pre_(NULL), pos_(0) {}
int64_t level_; ~BufNode() {}
struct BufNode *next_; char buf_[BUF_SIZE];
struct BufNode *pre_;
int64_t pos_;
}; };
struct BufList struct BufList
{ {
BufList() : head_(nullptr) {} BufList() : head_(nullptr) {}
BufNode *head_; BufNode *head_;
}; };
CStringBufMgr() : list_(), level_(-1), pos_(0) {} CStringBufMgr() : list_(), level_(-1), pos_(0), curr_(NULL) {}
~CStringBufMgr() {} ~CStringBufMgr() {}
static CStringBufMgr &get_thread_local_instance() static CStringBufMgr &get_thread_local_instance()
{ {
@ -176,45 +178,47 @@ public:
if (MIN_SIZE > BUF_SIZE - pos_) { if (MIN_SIZE > BUF_SIZE - pos_) {
pos_ = 0; pos_ = 0;
} }
} else if (NULL != curr_) {
curr_->pos_ += pos;
if (MIN_SIZE > BUF_SIZE - curr_->pos_) {
curr_->pos_ = 0;
}
BufNode *outer_layer = curr_->pre_;
curr_->pre_ = list_.head_;
list_.head_ = curr_;
curr_ = outer_layer;
} }
} }
int64_t get_buffer_len() int64_t acquire(char *&buffer)
{ {
return 0 == level_ ? (BUF_SIZE - pos_) : MIN_SIZE; int64_t buf_len = 0;
}
char *acquire()
{
char *buffer = NULL;
if (0 == level_) { if (0 == level_) {
buffer = local_buf_ + pos_; buffer = local_buf_ + pos_;
buf_len = BUF_SIZE - pos_;
} else { } else {
BufNode *node = NULL; BufNode *node = NULL;
node = list_.head_; node = list_.head_;
while (NULL != node) {
if (node->level_ > level_) {
node->level_ = level_;
break;
} else {
node = node->next_;
}
}
if ((NULL == node) && (NULL != (node = OB_NEW(BufNode, ObModIds::OB_THREAD_BUFFER)))) {
node->level_ = level_;
node->next_ = list_.head_;
list_.head_ = node;
}
if (NULL != node) { if (NULL != node) {
buffer = node->buf_; list_.head_ = node->pre_;
}
if ((NULL != node)
|| (NULL != (node = OB_NEW(BufNode, ObModIds::OB_THREAD_BUFFER)))) {
buffer = node->buf_ + node->pos_;
node->pre_ = curr_;
curr_ = node;
buf_len = BUF_SIZE - node->pos_;
} else {
buffer = NULL;
} }
} }
return buffer; return buf_len;
} }
void try_clear_list() void try_clear_list()
{ {
if (0 == level_) { if (0 == level_) {
while (NULL != list_.head_) { while (NULL != list_.head_) {
BufNode *node = list_.head_; BufNode *node = list_.head_;
list_.head_ = node->next_; list_.head_ = node->pre_;
OB_DELETE(BufNode, ObModIds::OB_THREAD_BUFFER, node); OB_DELETE(BufNode, ObModIds::OB_THREAD_BUFFER, node);
} }
} }
@ -224,6 +228,7 @@ private:
BufList list_; BufList list_;
int64_t level_; int64_t level_;
int64_t pos_; int64_t pos_;
BufNode *curr_;
}; };
template <typename T> template <typename T>
@ -233,11 +238,10 @@ const char *to_cstring(const T &obj, FalseType)
int64_t str_len = 0; int64_t str_len = 0;
CStringBufMgr &mgr = CStringBufMgr::get_thread_local_instance(); CStringBufMgr &mgr = CStringBufMgr::get_thread_local_instance();
mgr.inc_level(); mgr.inc_level();
buffer = mgr.acquire(); const int64_t buf_len = mgr.acquire(buffer);
if (OB_ISNULL(buffer)) { if (OB_ISNULL(buffer)) {
LIB_LOG_RET(ERROR, OB_ALLOCATE_MEMORY_FAILED, "buffer is NULL"); LIB_LOG_RET(ERROR, OB_ALLOCATE_MEMORY_FAILED, "buffer is NULL");
} else { } else {
const int64_t buf_len = mgr.get_buffer_len();
str_len = to_string(obj, buffer, buf_len -1); str_len = to_string(obj, buffer, buf_len -1);
if (str_len >= 0 && str_len < buf_len) { if (str_len >= 0 && str_len < buf_len) {
buffer[str_len] = '\0'; buffer[str_len] = '\0';

View File

@ -1117,11 +1117,10 @@ inline const char *get_vectorized_row_str(ObEvalCtx &eval_ctx,
int64_t str_len = 0; int64_t str_len = 0;
CStringBufMgr &mgr = CStringBufMgr::get_thread_local_instance(); CStringBufMgr &mgr = CStringBufMgr::get_thread_local_instance();
mgr.inc_level(); mgr.inc_level();
buffer = mgr.acquire(); const int64_t buf_len = mgr.acquire(buffer);
if (OB_ISNULL(buffer)) { if (OB_ISNULL(buffer)) {
LIB_LOG_RET(ERROR, OB_ALLOCATE_MEMORY_FAILED, "buffer is NULL"); LIB_LOG_RET(ERROR, OB_ALLOCATE_MEMORY_FAILED, "buffer is NULL");
} else { } else {
const int64_t buf_len = mgr.get_buffer_len();
databuff_printf(buffer, buf_len, str_len, "vectorized_rows(%ld)=", index); databuff_printf(buffer, buf_len, str_len, "vectorized_rows(%ld)=", index);
str_len += to_string(ROWEXPR2STR(eval_ctx, exprs), buffer + str_len, buf_len - str_len - 1); str_len += to_string(ROWEXPR2STR(eval_ctx, exprs), buffer + str_len, buf_len - str_len - 1);
if (str_len >= 0 && str_len < buf_len) { if (str_len >= 0 && str_len < buf_len) {