fast_buffer support options: binary_mode and check_capacity
parent
558670bc63
commit
e4898affdd
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -17,12 +17,14 @@
|
|||
#define __FAST_BUFFER_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#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);
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ int fast_multi_sock_client_init_ex(FastMultiSockClient *client,
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue