fast_buffer support options: binary_mode and check_capacity

use_iouring
YuQing 2025-08-05 11:44:04 +08:00
parent 558670bc63
commit e4898affdd
5 changed files with 243 additions and 44 deletions

1
.gitignore vendored
View File

@ -64,6 +64,7 @@ src/tests/test_thread_local
src/tests/test_memcpy src/tests/test_memcpy
src/tests/mblock_benchmark src/tests/mblock_benchmark
src/tests/cpool_benchmark src/tests/cpool_benchmark
src/tests/test_fast_buffer
# other # other
*.swp *.swp

View File

@ -26,23 +26,28 @@
#include "fc_memory.h" #include "fc_memory.h"
#include "fast_buffer.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->length = 0;
buffer->binary_mode = binary_mode;
if (init_capacity > 0) if (init_capacity > 0)
{ {
buffer->alloc_size = init_capacity; buffer->alloc_size = init_capacity;
buffer->check_capacity = check_capacity;
} }
else else
{ {
buffer->alloc_size = 256; buffer->alloc_size = 256;
buffer->check_capacity = true;
} }
buffer->data = (char *)fc_malloc(buffer->alloc_size); buffer->data = (char *)fc_malloc(buffer->alloc_size);
if (buffer->data == NULL) if (buffer->data == NULL)
{ {
return ENOMEM; return ENOMEM;
} }
*(buffer->data) = '\0';
fast_buffer_set_null_terminator(buffer);
return 0; return 0;
} }
@ -88,7 +93,9 @@ int fast_buffer_set_capacity(FastBuffer *buffer, const int capacity)
if (buffer->length > 0) { if (buffer->length > 0) {
memcpy(buff, buffer->data, buffer->length); memcpy(buff, buffer->data, buffer->length);
*(buff + buffer->length) = '\0'; if (!buffer->binary_mode) {
*(buff + buffer->length) = '\0';
}
} }
free(buffer->data); free(buffer->data);
@ -127,7 +134,7 @@ int fast_buffer_append(FastBuffer *buffer, const char *format, ...)
} }
else else
{ {
*(buffer->data + buffer->length) = '\0'; //restore fast_buffer_set_null_terminator(buffer); //restore
} }
} }
return result; 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); memcpy(buffer->data + buffer->length, data, len);
buffer->length += len; buffer->length += len;
*(buffer->data + buffer->length) = '\0'; fast_buffer_set_null_terminator(buffer);
return 0; return 0;
} }
@ -171,32 +178,6 @@ int fast_buffer_append_binary(FastBuffer *buffer,
return 0; 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) int fast_buffer_append_file(FastBuffer *buffer, const char *filename)
{ {
struct stat st; struct stat st;

View File

@ -17,12 +17,14 @@
#define __FAST_BUFFER_H__ #define __FAST_BUFFER_H__
#include <stdint.h> #include <stdint.h>
#include "common_define.h" #include "shared_func.h"
typedef struct fast_buffer { typedef struct fast_buffer {
char *data; char *data;
int alloc_size; int alloc_size;
int length; int length;
bool binary_mode;
bool check_capacity;
} FastBuffer; } FastBuffer;
#ifdef __cplusplus #ifdef __cplusplus
@ -39,26 +41,39 @@ static inline char *fast_buffer_data(FastBuffer *buffer)
return buffer->data; 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) 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) #define fast_buffer_clear(buffer) fast_buffer_reset(buffer)
static inline void fast_buffer_reset(FastBuffer *buffer) static inline void fast_buffer_reset(FastBuffer *buffer)
{ {
buffer->length = 0; buffer->length = 0;
*buffer->data = '\0'; fast_buffer_set_null_terminator(buffer);
} }
void fast_buffer_destroy(FastBuffer *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); int fast_buffer_set_capacity(FastBuffer *buffer, const int capacity);
static inline int fast_buffer_check_capacity(FastBuffer *buffer, 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, int fast_buffer_append_binary(FastBuffer *buffer,
const void *data, const int len); 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); int fast_buffer_append_file(FastBuffer *buffer, const char *filename);

View File

@ -85,7 +85,7 @@ int fast_multi_sock_client_init_ex(FastMultiSockClient *client,
} }
for (i=0; i<entry_count; i++) { for (i=0; i<entry_count; i++) {
if ((result=fast_buffer_init_ex(&entries[i].recv_buffer, if ((result=fast_buffer_init1(&entries[i].recv_buffer,
new_init_recv_buffer_size)) != 0) new_init_recv_buffer_size)) != 0)
{ {
return result; return result;

View File

@ -0,0 +1,164 @@
/*
* Copyright (c) 2020 YuQing <384681@qq.com>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#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<LOOP; i++) {
fast_buffer_reset(&buffer);
log_pack_by_sprintf(&record, &buffer, have_extra_field);
}
sprintf_time_ms = (get_current_time_us() - start_time_us) / 1000;
start_time_us = get_current_time_us();
for (i=0; i<LOOP; i++) {
fast_buffer_reset(&buffer);
log_pack_by_append(&record, &buffer, have_extra_field);
}
append_time_ms = (get_current_time_us() - start_time_us) / 1000;
if (append_time_ms > 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;
}