From e4898affdd30344680d0ee9ebc61b0e940431c1b Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Tue, 5 Aug 2025 11:44:04 +0800 Subject: [PATCH] fast_buffer support options: binary_mode and check_capacity --- .gitignore | 1 + src/fast_buffer.c | 43 +++------ src/fast_buffer.h | 77 +++++++++++++--- src/multi_socket_client.c | 2 +- src/tests/test_fast_buffer.c | 164 +++++++++++++++++++++++++++++++++++ 5 files changed, 243 insertions(+), 44 deletions(-) create mode 100644 src/tests/test_fast_buffer.c diff --git a/.gitignore b/.gitignore index f74980c..d0a20d0 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,7 @@ src/tests/test_thread_local src/tests/test_memcpy src/tests/mblock_benchmark src/tests/cpool_benchmark +src/tests/test_fast_buffer # other *.swp diff --git a/src/fast_buffer.c b/src/fast_buffer.c index c48b522..d299bcd 100644 --- a/src/fast_buffer.c +++ b/src/fast_buffer.c @@ -26,23 +26,28 @@ #include "fc_memory.h" #include "fast_buffer.h" -int fast_buffer_init_ex(FastBuffer *buffer, const int init_capacity) +int fast_buffer_init_ex(FastBuffer *buffer, const int init_capacity, + const bool binary_mode, const bool check_capacity) { buffer->length = 0; + buffer->binary_mode = binary_mode; if (init_capacity > 0) { buffer->alloc_size = init_capacity; + buffer->check_capacity = check_capacity; } else { buffer->alloc_size = 256; + buffer->check_capacity = true; } buffer->data = (char *)fc_malloc(buffer->alloc_size); if (buffer->data == NULL) { return ENOMEM; } - *(buffer->data) = '\0'; + + fast_buffer_set_null_terminator(buffer); return 0; } @@ -88,7 +93,9 @@ int fast_buffer_set_capacity(FastBuffer *buffer, const int capacity) if (buffer->length > 0) { memcpy(buff, buffer->data, buffer->length); - *(buff + buffer->length) = '\0'; + if (!buffer->binary_mode) { + *(buff + buffer->length) = '\0'; + } } free(buffer->data); @@ -127,7 +134,7 @@ int fast_buffer_append(FastBuffer *buffer, const char *format, ...) } else { - *(buffer->data + buffer->length) = '\0'; //restore + fast_buffer_set_null_terminator(buffer); //restore } } return result; @@ -148,7 +155,7 @@ int fast_buffer_append_buff(FastBuffer *buffer, const char *data, const int len) memcpy(buffer->data + buffer->length, data, len); buffer->length += len; - *(buffer->data + buffer->length) = '\0'; + fast_buffer_set_null_terminator(buffer); return 0; } @@ -171,32 +178,6 @@ int fast_buffer_append_binary(FastBuffer *buffer, return 0; } -int fast_buffer_append_int(FastBuffer *buffer, const int n) -{ - int result; - - if ((result=fast_buffer_check(buffer, 16)) != 0) - { - return result; - } - - buffer->length += fc_itoa(n, buffer->data + buffer->length); - return 0; -} - -int fast_buffer_append_int64(FastBuffer *buffer, const int64_t n) -{ - int result; - - if ((result=fast_buffer_check(buffer, 32)) != 0) - { - return result; - } - - buffer->length += fc_itoa(n, buffer->data + buffer->length); - return 0; -} - int fast_buffer_append_file(FastBuffer *buffer, const char *filename) { struct stat st; diff --git a/src/fast_buffer.h b/src/fast_buffer.h index 735d1ac..65800c2 100644 --- a/src/fast_buffer.h +++ b/src/fast_buffer.h @@ -17,12 +17,14 @@ #define __FAST_BUFFER_H__ #include -#include "common_define.h" +#include "shared_func.h" typedef struct fast_buffer { - char *data; - int alloc_size; - int length; + char *data; + int alloc_size; + int length; + bool binary_mode; + bool check_capacity; } FastBuffer; #ifdef __cplusplus @@ -39,26 +41,39 @@ static inline char *fast_buffer_data(FastBuffer *buffer) return buffer->data; } -int fast_buffer_init_ex(FastBuffer *buffer, const int init_capacity); +int fast_buffer_init_ex(FastBuffer *buffer, const int init_capacity, + const bool binary_mode, const bool check_capacity); + +static inline int fast_buffer_init1(FastBuffer *buffer, const int init_capacity) +{ + const bool binary_mode = false; + const bool check_capacity = true; + return fast_buffer_init_ex(buffer, init_capacity, + binary_mode, check_capacity); +} static inline int fast_buffer_init(FastBuffer *buffer) { - return fast_buffer_init_ex(buffer, 0); + const int init_capacity = 0; + return fast_buffer_init1(buffer, init_capacity); } +#define fast_buffer_set_null_terminator(buffer) \ + if (!buffer->binary_mode) *(buffer->data + buffer->length) = '\0' + +#define fast_buffer_check(buffer, inc_len) \ + ((buffer)->check_capacity ? fast_buffer_check_inc_size(buffer, inc_len) : 0) + #define fast_buffer_clear(buffer) fast_buffer_reset(buffer) static inline void fast_buffer_reset(FastBuffer *buffer) { buffer->length = 0; - *buffer->data = '\0'; + fast_buffer_set_null_terminator(buffer); } void fast_buffer_destroy(FastBuffer *buffer); -#define fast_buffer_check(buffer, inc_len) \ - fast_buffer_check_inc_size(buffer, inc_len) - int fast_buffer_set_capacity(FastBuffer *buffer, const int capacity); static inline int fast_buffer_check_capacity(FastBuffer *buffer, @@ -86,9 +101,47 @@ int fast_buffer_append_buff(FastBuffer *buffer, int fast_buffer_append_binary(FastBuffer *buffer, const void *data, const int len); -int fast_buffer_append_int(FastBuffer *buffer, const int n); +static inline int fast_buffer_append_char(FastBuffer *buffer, const char ch) +{ + int result; -int fast_buffer_append_int64(FastBuffer *buffer, const int64_t n); + if ((result=fast_buffer_check(buffer, 1)) != 0) + { + return result; + } + + *(buffer->data + buffer->length++) = ch; + fast_buffer_set_null_terminator(buffer); + return 0; +} + +static inline int fast_buffer_append_int(FastBuffer *buffer, const int n) +{ + int result; + + if ((result=fast_buffer_check(buffer, 16)) != 0) + { + return result; + } + + buffer->length += fc_itoa(n, buffer->data + buffer->length); + fast_buffer_set_null_terminator(buffer); + return 0; +} + +static inline int fast_buffer_append_int64(FastBuffer *buffer, const int64_t n) +{ + int result; + + if ((result=fast_buffer_check(buffer, 32)) != 0) + { + return result; + } + + buffer->length += fc_itoa(n, buffer->data + buffer->length); + fast_buffer_set_null_terminator(buffer); + return 0; +} int fast_buffer_append_file(FastBuffer *buffer, const char *filename); diff --git a/src/multi_socket_client.c b/src/multi_socket_client.c index 82d99ac..428207c 100644 --- a/src/multi_socket_client.c +++ b/src/multi_socket_client.c @@ -85,7 +85,7 @@ int fast_multi_sock_client_init_ex(FastMultiSockClient *client, } for (i=0; i + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the Lesser GNU General Public License, version 3 + * or later ("LGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the Lesser GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fastcommon/logger.h" +#include "fastcommon/fast_buffer.h" +#include "fastcommon/sched_thread.h" + +typedef enum { + DA_SLICE_TYPE_FILE = 'F', /* in file slice */ + DA_SLICE_TYPE_CACHE = 'C', /* in memory cache */ + DA_SLICE_TYPE_ALLOC = 'A' /* allocate slice (index and space allocate only) */ +} DASliceType; + +typedef struct { + int64_t version; + uint64_t trunk_id; //0 for not inited + uint32_t length; //data length + uint32_t offset; //space offset + uint32_t size; //space size +} DAPieceFieldStorage; + +typedef struct { + int64_t version; //for stable sort only + uint64_t oid; //object ID + uint64_t fid; //field ID (key) + uint32_t extra; //such as slice offset + char op_type; + DASliceType slice_type; + DAPieceFieldStorage storage; +} DATrunkSpaceLogRecord; + +static inline void log_pack_by_append(const DATrunkSpaceLogRecord + *record, FastBuffer *buffer, const bool have_extra_field) +{ + fast_buffer_append_int64(buffer, (uint32_t)g_current_time); + fast_buffer_append_char(buffer, ' '); + fast_buffer_append_int64(buffer, record->storage.version); + fast_buffer_append_char(buffer, ' '); + fast_buffer_append_int64(buffer, record->oid); + fast_buffer_append_char(buffer, ' '); + fast_buffer_append_int64(buffer, record->fid); + fast_buffer_append_char(buffer, ' '); + fast_buffer_append_char(buffer, record->op_type); + fast_buffer_append_char(buffer, ' '); + fast_buffer_append_int64(buffer, record->storage.trunk_id); + fast_buffer_append_char(buffer, ' '); + fast_buffer_append_int64(buffer, record->storage.length); + fast_buffer_append_char(buffer, ' '); + fast_buffer_append_int64(buffer, record->storage.offset); + fast_buffer_append_char(buffer, ' '); + fast_buffer_append_int64(buffer, record->storage.size); + fast_buffer_append_char(buffer, ' '); + fast_buffer_append_char(buffer, record->slice_type); + + if (have_extra_field) { + fast_buffer_append_char(buffer, ' '); + fast_buffer_append_char(buffer, record->extra); + fast_buffer_append_char(buffer, '\n'); + } else { + fast_buffer_append_char(buffer, '\n'); + } +} + +static inline void log_pack_by_sprintf(const DATrunkSpaceLogRecord + *record, FastBuffer *buffer, const bool have_extra_field) +{ + buffer->length += sprintf(buffer->data + buffer->length, + "%u %"PRId64" %"PRId64" %"PRId64" %c %"PRId64" %u %u %u %c", + (uint32_t)g_current_time, record->storage.version, + record->oid, record->fid, record->op_type, + record->storage.trunk_id, record->storage.length, + record->storage.offset, record->storage.size, + record->slice_type); + if (have_extra_field) { + buffer->length += sprintf(buffer->data + buffer->length, + " %u\n", record->extra); + } else { + *(buffer->data + buffer->length++) = '\n'; + } +} + +int main(int argc, char *argv[]) +{ + const bool binary_mode = true; + const bool check_capacity = false; + const bool have_extra_field = false; + const int LOOP = 10 * 1000 * 1000; + int result; + int i; + int64_t start_time_us; + int append_time_ms; + int sprintf_time_ms; + double ratio; + FastBuffer buffer; + DATrunkSpaceLogRecord record; + + log_init(); + g_current_time = time(NULL); + if ((result=fast_buffer_init_ex(&buffer, 256, + binary_mode, check_capacity)) != 0) + { + return result; + } + + memset(&record, 0, sizeof(record)); + record.op_type = 'C'; + record.slice_type = DA_SLICE_TYPE_FILE; + record.storage.version = 1111; + record.oid = 9007211709265131LL; + record.fid = 0; + record.storage.trunk_id = 61; + record.storage.length = 62; + record.storage.offset = 12345; + record.storage.size = 64; + + start_time_us = get_current_time_us(); + for (i=0; i 0) { + ratio = (double)sprintf_time_ms / (double)append_time_ms; + } else { + ratio = 1.0; + } + + printf("sprintf time: %d ms, append time: %d ms, " + "sprintf time / append time: %d%%\n", + sprintf_time_ms, append_time_ms, + (int)(ratio * 100.00)); + + fast_buffer_destroy(&buffer); + return 0; +}