json decode supports memory pool for persistency

vote_node
YuQing 2022-06-04 12:41:07 +08:00
parent 009d33480f
commit 0b539bbba2
4 changed files with 109 additions and 30 deletions

View File

@ -1,5 +1,5 @@
Version 1.58 2022-05-29 Version 1.58 2022-06-04
* add function conn_pool_connect_server_ex1 to support service name * add function conn_pool_connect_server_ex1 to support service name
* add function conn_pool_get_connection_ex to support service name * add function conn_pool_get_connection_ex to support service name
* add function iniGetCharValueEx * add function iniGetCharValueEx

View File

@ -126,7 +126,7 @@ static int next_json_element(fc_json_context_t *context)
int unicode; int unicode;
int i; int i;
dest = context->element.str; dest = context->decode.element.str;
quote_ch = *context->p; quote_ch = *context->p;
if (quote_ch == '\"' || quote_ch == '\'') { if (quote_ch == '\"' || quote_ch == '\'') {
context->p++; context->p++;
@ -224,7 +224,7 @@ static int next_json_element(fc_json_context_t *context)
} }
*dest = '\0'; *dest = '\0';
context->element.len = dest - context->element.str; context->decode.element.len = dest - context->decode.element.str;
return 0; return 0;
} }
@ -288,8 +288,8 @@ static int prepare_json_parse(fc_json_context_t *context,
} }
} }
context->element.str = context->output.buff; context->decode.element.str = context->output.buff;
context->element.len = 0; context->decode.element.len = 0;
context->str = input->str; context->str = input->str;
context->p = input->str + 1; context->p = input->str + 1;
context->end = input->str + input->len - 1; context->end = input->str + input->len - 1;
@ -392,6 +392,18 @@ int fc_encode_json_map_ex(fc_json_context_t *context,
return 0; return 0;
} }
#define JSON_DECODE_COPY_STRING(ctx, input, dest, src) \
do { \
if ((context->error_no=fast_mpool_alloc_string_ex2( \
&ctx->decode.mpool, dest, src)) != 0) \
{ \
set_parse_error(input->str, ctx->p, EXPECT_STR_LEN, \
"out of memory", &ctx->error_info, ctx->error_size); \
return NULL; \
} \
} while (0)
const fc_json_array_t *fc_decode_json_array(fc_json_context_t const fc_json_array_t *fc_decode_json_array(fc_json_context_t
*context, const string_t *input) *context, const string_t *input)
{ {
@ -445,8 +457,14 @@ const fc_json_array_t *fc_decode_json_array(fc_json_context_t
return NULL; return NULL;
} }
context->jarray.elements[context->jarray.count++] = context->element; if (context->decode.use_mpool) {
context->element.str += context->element.len + 1; JSON_DECODE_COPY_STRING(context, input, context->jarray.elements +
context->jarray.count++, &context->decode.element);
} else {
context->jarray.elements[context->jarray.count++] =
context->decode.element;
}
context->decode.element.str += context->decode.element.len + 1;
} }
return &context->jarray; return &context->jarray;
@ -496,8 +514,8 @@ const fc_json_map_t *fc_decode_json_map(fc_json_context_t
} }
context->p++; //skip colon context->p++; //skip colon
kv_pair.key = context->element; kv_pair.key = context->decode.element;
context->element.str += context->element.len + 1; context->decode.element.str += context->decode.element.len + 1;
while (context->p < context->end && JSON_SPACE(*context->p)) { while (context->p < context->end && JSON_SPACE(*context->p)) {
context->p++; context->p++;
@ -520,8 +538,8 @@ const fc_json_map_t *fc_decode_json_map(fc_json_context_t
} }
} }
kv_pair.value = context->element; kv_pair.value = context->decode.element;
context->element.str += context->element.len + 1; context->decode.element.str += context->decode.element.len + 1;
if ((context->error_no=check_alloc_array(context, if ((context->error_no=check_alloc_array(context,
(fc_common_array_t *) (fc_common_array_t *)
@ -529,7 +547,17 @@ const fc_json_map_t *fc_decode_json_map(fc_json_context_t
{ {
return NULL; return NULL;
} }
context->jmap.elements[context->jmap.count++] = kv_pair;
if (context->decode.use_mpool) {
key_value_pair_t *dest;
dest = context->jmap.elements + context->jmap.count++;
JSON_DECODE_COPY_STRING(context, input,
&dest->key, &kv_pair.key);
JSON_DECODE_COPY_STRING(context, input,
&dest->value, &kv_pair.value);
} else {
context->jmap.elements[context->jmap.count++] = kv_pair;
}
} }
return &context->jmap; return &context->jmap;

View File

@ -24,6 +24,7 @@
#include <time.h> #include <time.h>
#include "common_define.h" #include "common_define.h"
#include "shared_func.h" #include "shared_func.h"
#include "fast_mpool.h"
#define FC_JSON_TYPE_STRING 1 #define FC_JSON_TYPE_STRING 1
#define FC_JSON_TYPE_ARRAY 2 #define FC_JSON_TYPE_ARRAY 2
@ -44,8 +45,12 @@ DEFINE_ARRAY_STRUCT(string_t, fc_json_array_t);
DEFINE_ARRAY_STRUCT(key_value_pair_t, fc_json_map_t); DEFINE_ARRAY_STRUCT(key_value_pair_t, fc_json_map_t);
typedef struct { typedef struct {
BufferInfo output; //for json encode BufferInfo output; //for json encode/decode
string_t element; //string allocator use output buffer struct {
struct fast_mpool_man mpool;
string_t element; //string allocator use output buffer
bool use_mpool;
} decode;
int init_buff_size; int init_buff_size;
int error_no; int error_no;
int error_size; int error_size;
@ -119,11 +124,15 @@ extern "C" {
} }
static inline int fc_init_json_context_ex(fc_json_context_t *ctx, static inline int fc_init_json_context_ex(fc_json_context_t *ctx,
const int init_buff_size, char *error_info, const int error_size) const bool decode_use_mpool, const int alloc_size_once,
const int init_buff_size, char *error_info,
const int error_size)
{ {
const int discard_size = 0;
ctx->output.buff = NULL; ctx->output.buff = NULL;
ctx->output.alloc_size = ctx->output.length = 0; ctx->output.alloc_size = ctx->output.length = 0;
FC_SET_STRING_NULL(ctx->element); FC_SET_STRING_NULL(ctx->decode.element);
if (init_buff_size > 0) { if (init_buff_size > 0) {
ctx->init_buff_size = init_buff_size; ctx->init_buff_size = init_buff_size;
} else { } else {
@ -134,13 +143,30 @@ extern "C" {
ctx->error_no = 0; ctx->error_no = 0;
fc_set_json_error_buffer(ctx, error_info, error_size); fc_set_json_error_buffer(ctx, error_info, error_size);
return 0; ctx->decode.use_mpool = decode_use_mpool;
if (decode_use_mpool) {
return fast_mpool_init(&ctx->decode.mpool,
alloc_size_once, discard_size);
} else {
return 0;
}
} }
static inline int fc_init_json_context(fc_json_context_t *ctx) static inline int fc_init_json_context(fc_json_context_t *ctx)
{ {
const bool decode_use_mpool = false;
const int alloc_size_once = 0;
const int init_buff_size = 0; const int init_buff_size = 0;
return fc_init_json_context_ex(ctx, init_buff_size, NULL, 0);
return fc_init_json_context_ex(ctx, decode_use_mpool,
alloc_size_once, init_buff_size, NULL, 0);
}
static inline void fc_reset_json_context(fc_json_context_t *ctx)
{
if (ctx->decode.use_mpool) {
fast_mpool_reset(&ctx->decode.mpool);
}
} }
static inline void fc_destroy_json_context(fc_json_context_t *ctx) static inline void fc_destroy_json_context(fc_json_context_t *ctx)
@ -148,6 +174,9 @@ extern "C" {
fc_free_buffer(&ctx->output); fc_free_buffer(&ctx->output);
fc_free_json_array(&ctx->jarray); fc_free_json_array(&ctx->jarray);
fc_free_json_map(&ctx->jmap); fc_free_json_map(&ctx->jmap);
if (ctx->decode.use_mpool) {
fast_mpool_destroy(&ctx->decode.mpool);
}
} }
static inline int fc_json_parser_get_error_no(fc_json_context_t *ctx) static inline int fc_json_parser_get_error_no(fc_json_context_t *ctx)

View File

@ -28,12 +28,16 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
const bool decode_use_mpool = false;
const int alloc_size_once = 1024;
const int init_buff_size = 1024;
int result; int result;
int json_type; int json_type;
fc_json_context_t json_ctx; fc_json_context_t json_ctx;
char error_info[256]; char error_info[256];
string_t input; string_t input;
BufferInfo output; BufferInfo buffer;
const BufferInfo *output;
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "Usage: %s <json_string | json_array | json_map>\n", fprintf(stderr, "Usage: %s <json_string | json_array | json_map>\n",
@ -43,12 +47,13 @@ int main(int argc, char *argv[])
log_init(); log_init();
if ((result=fc_init_json_context_ex(&json_ctx, 1024, if ((result=fc_init_json_context_ex(&json_ctx, decode_use_mpool,
error_info, sizeof(error_info))) != 0) alloc_size_once, init_buff_size, error_info,
sizeof(error_info))) != 0)
{ {
return result; return result;
} }
memset(&output, 0, sizeof(output)); memset(&buffer, 0, sizeof(buffer));
input.str = argv[1]; input.str = argv[1];
input.len = strlen(input.str); input.len = strlen(input.str);
@ -61,14 +66,23 @@ int main(int argc, char *argv[])
return fc_json_parser_get_error_no(&json_ctx); return fc_json_parser_get_error_no(&json_ctx);
} }
if ((result=fc_encode_json_array_ex(&json_ctx, array->elements, if (decode_use_mpool) {
array->count, &output)) != 0) output = fc_encode_json_array(&json_ctx,
{ array->elements, array->count);
result = fc_json_parser_get_error_no(&json_ctx);
} else {
output = &buffer;
result = fc_encode_json_array_ex(&json_ctx,
array->elements, array->count, &buffer);
}
if (result != 0) {
fprintf(stderr, "encode json array fail, %s\n", error_info); fprintf(stderr, "encode json array fail, %s\n", error_info);
return result; return result;
} }
printf("%.*s\n", output.length, output.buff); printf("%.*s\n", output->length, output->buff);
fc_free_buffer(&buffer);
} else if (json_type == FC_JSON_TYPE_MAP) { } else if (json_type == FC_JSON_TYPE_MAP) {
const fc_json_map_t *map; const fc_json_map_t *map;
@ -77,14 +91,22 @@ int main(int argc, char *argv[])
return fc_json_parser_get_error_no(&json_ctx); return fc_json_parser_get_error_no(&json_ctx);
} }
if ((result=fc_encode_json_map_ex(&json_ctx, map->elements, if (decode_use_mpool) {
map->count, &output)) != 0) output = fc_encode_json_map(&json_ctx,
{ map->elements, map->count);
result = fc_json_parser_get_error_no(&json_ctx);
} else {
output = &buffer;
result = fc_encode_json_map_ex(&json_ctx,
map->elements, map->count, &buffer);
}
if (result != 0) {
fprintf(stderr, "encode json map fail, %s\n", error_info); fprintf(stderr, "encode json map fail, %s\n", error_info);
return result; return result;
} }
printf("%.*s\n", output.length, output.buff); printf("%.*s\n", output->length, output->buff);
fc_free_buffer(&buffer);
} else { } else {
fprintf(stderr, "string\n"); fprintf(stderr, "string\n");
} }