Add compact json option for emitter
JSON format is largely meant for machine-machine communication, so adding the option to the emitter. According to local testing, the savings in terms of bytes outputted is around 50% for stats printing and around 25% for prof log printing.
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
typedef enum emitter_output_e emitter_output_t;
|
||||
enum emitter_output_e {
|
||||
emitter_output_json,
|
||||
emitter_output_json_compact,
|
||||
emitter_output_table
|
||||
};
|
||||
|
||||
@@ -75,6 +76,12 @@ struct emitter_s {
|
||||
bool emitted_key;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
emitter_outputs_json(emitter_t *emitter) {
|
||||
return emitter->output == emitter_output_json ||
|
||||
emitter->output == emitter_output_json_compact;
|
||||
}
|
||||
|
||||
/* Internal convenience function. Write to the emitter the given string. */
|
||||
JEMALLOC_FORMAT_PRINTF(2, 3)
|
||||
static inline void
|
||||
@@ -135,7 +142,7 @@ emitter_print_value(emitter_t *emitter, emitter_justify_t justify, int width,
|
||||
|
||||
switch (value_type) {
|
||||
case emitter_type_bool:
|
||||
emitter_printf(emitter,
|
||||
emitter_printf(emitter,
|
||||
emitter_gen_fmt(fmt, FMT_SIZE, "%s", justify, width),
|
||||
*(const bool *)value ? "true" : "false");
|
||||
break;
|
||||
@@ -159,7 +166,7 @@ emitter_print_value(emitter_t *emitter, emitter_justify_t justify, int width,
|
||||
* anywhere near the fmt size.
|
||||
*/
|
||||
assert(str_written < BUF_SIZE);
|
||||
emitter_printf(emitter,
|
||||
emitter_printf(emitter,
|
||||
emitter_gen_fmt(fmt, FMT_SIZE, "%s", justify, width), buf);
|
||||
break;
|
||||
case emitter_type_uint32:
|
||||
@@ -196,6 +203,7 @@ static inline void
|
||||
emitter_indent(emitter_t *emitter) {
|
||||
int amount = emitter->nesting_depth;
|
||||
const char *indent_str;
|
||||
assert(emitter->output != emitter_output_json_compact);
|
||||
if (emitter->output == emitter_output_json) {
|
||||
indent_str = "\t";
|
||||
} else {
|
||||
@@ -209,12 +217,18 @@ emitter_indent(emitter_t *emitter) {
|
||||
|
||||
static inline void
|
||||
emitter_json_key_prefix(emitter_t *emitter) {
|
||||
assert(emitter_outputs_json(emitter));
|
||||
if (emitter->emitted_key) {
|
||||
emitter->emitted_key = false;
|
||||
return;
|
||||
}
|
||||
emitter_printf(emitter, "%s\n", emitter->item_at_depth ? "," : "");
|
||||
emitter_indent(emitter);
|
||||
if (emitter->item_at_depth) {
|
||||
emitter_printf(emitter, ",");
|
||||
}
|
||||
if (emitter->output != emitter_output_json_compact) {
|
||||
emitter_printf(emitter, "\n");
|
||||
emitter_indent(emitter);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@@ -227,22 +241,23 @@ emitter_init(emitter_t *emitter, emitter_output_t emitter_output,
|
||||
emitter->write_cb = write_cb;
|
||||
emitter->cbopaque = cbopaque;
|
||||
emitter->item_at_depth = false;
|
||||
emitter->emitted_key = false;
|
||||
emitter->emitted_key = false;
|
||||
emitter->nesting_depth = 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* JSON public API. */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Emits a key (e.g. as appears in an object). The next json entity emitted will
|
||||
* be the corresponding value.
|
||||
*/
|
||||
static inline void
|
||||
emitter_json_key(emitter_t *emitter, const char *json_key) {
|
||||
if (emitter->output == emitter_output_json) {
|
||||
if (emitter_outputs_json(emitter)) {
|
||||
emitter_json_key_prefix(emitter);
|
||||
emitter_printf(emitter, "\"%s\": ", json_key);
|
||||
emitter_printf(emitter, "\"%s\":%s", json_key,
|
||||
emitter->output == emitter_output_json_compact ? "" : " ");
|
||||
emitter->emitted_key = true;
|
||||
}
|
||||
}
|
||||
@@ -250,7 +265,7 @@ emitter_json_key(emitter_t *emitter, const char *json_key) {
|
||||
static inline void
|
||||
emitter_json_value(emitter_t *emitter, emitter_type_t value_type,
|
||||
const void *value) {
|
||||
if (emitter->output == emitter_output_json) {
|
||||
if (emitter_outputs_json(emitter)) {
|
||||
emitter_json_key_prefix(emitter);
|
||||
emitter_print_value(emitter, emitter_justify_none, -1,
|
||||
value_type, value);
|
||||
@@ -268,7 +283,7 @@ emitter_json_kv(emitter_t *emitter, const char *json_key,
|
||||
|
||||
static inline void
|
||||
emitter_json_array_begin(emitter_t *emitter) {
|
||||
if (emitter->output == emitter_output_json) {
|
||||
if (emitter_outputs_json(emitter)) {
|
||||
emitter_json_key_prefix(emitter);
|
||||
emitter_printf(emitter, "[");
|
||||
emitter_nest_inc(emitter);
|
||||
@@ -284,18 +299,20 @@ emitter_json_array_kv_begin(emitter_t *emitter, const char *json_key) {
|
||||
|
||||
static inline void
|
||||
emitter_json_array_end(emitter_t *emitter) {
|
||||
if (emitter->output == emitter_output_json) {
|
||||
if (emitter_outputs_json(emitter)) {
|
||||
assert(emitter->nesting_depth > 0);
|
||||
emitter_nest_dec(emitter);
|
||||
emitter_printf(emitter, "\n");
|
||||
emitter_indent(emitter);
|
||||
if (emitter->output != emitter_output_json_compact) {
|
||||
emitter_printf(emitter, "\n");
|
||||
emitter_indent(emitter);
|
||||
}
|
||||
emitter_printf(emitter, "]");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
emitter_json_object_begin(emitter_t *emitter) {
|
||||
if (emitter->output == emitter_output_json) {
|
||||
if (emitter_outputs_json(emitter)) {
|
||||
emitter_json_key_prefix(emitter);
|
||||
emitter_printf(emitter, "{");
|
||||
emitter_nest_inc(emitter);
|
||||
@@ -311,11 +328,13 @@ emitter_json_object_kv_begin(emitter_t *emitter, const char *json_key) {
|
||||
|
||||
static inline void
|
||||
emitter_json_object_end(emitter_t *emitter) {
|
||||
if (emitter->output == emitter_output_json) {
|
||||
if (emitter_outputs_json(emitter)) {
|
||||
assert(emitter->nesting_depth > 0);
|
||||
emitter_nest_dec(emitter);
|
||||
emitter_printf(emitter, "\n");
|
||||
emitter_indent(emitter);
|
||||
if (emitter->output != emitter_output_json_compact) {
|
||||
emitter_printf(emitter, "\n");
|
||||
emitter_indent(emitter);
|
||||
}
|
||||
emitter_printf(emitter, "}");
|
||||
}
|
||||
}
|
||||
@@ -420,7 +439,7 @@ emitter_kv_note(emitter_t *emitter, const char *json_key, const char *table_key,
|
||||
emitter_type_t value_type, const void *value,
|
||||
const char *table_note_key, emitter_type_t table_note_value_type,
|
||||
const void *table_note_value) {
|
||||
if (emitter->output == emitter_output_json) {
|
||||
if (emitter_outputs_json(emitter)) {
|
||||
emitter_json_key(emitter, json_key);
|
||||
emitter_json_value(emitter, value_type, value);
|
||||
} else {
|
||||
@@ -440,7 +459,7 @@ emitter_kv(emitter_t *emitter, const char *json_key, const char *table_key,
|
||||
static inline void
|
||||
emitter_dict_begin(emitter_t *emitter, const char *json_key,
|
||||
const char *table_header) {
|
||||
if (emitter->output == emitter_output_json) {
|
||||
if (emitter_outputs_json(emitter)) {
|
||||
emitter_json_key(emitter, json_key);
|
||||
emitter_json_object_begin(emitter);
|
||||
} else {
|
||||
@@ -450,7 +469,7 @@ emitter_dict_begin(emitter_t *emitter, const char *json_key,
|
||||
|
||||
static inline void
|
||||
emitter_dict_end(emitter_t *emitter) {
|
||||
if (emitter->output == emitter_output_json) {
|
||||
if (emitter_outputs_json(emitter)) {
|
||||
emitter_json_object_end(emitter);
|
||||
} else {
|
||||
emitter_table_dict_end(emitter);
|
||||
@@ -459,7 +478,7 @@ emitter_dict_end(emitter_t *emitter) {
|
||||
|
||||
static inline void
|
||||
emitter_begin(emitter_t *emitter) {
|
||||
if (emitter->output == emitter_output_json) {
|
||||
if (emitter_outputs_json(emitter)) {
|
||||
assert(emitter->nesting_depth == 0);
|
||||
emitter_printf(emitter, "{");
|
||||
emitter_nest_inc(emitter);
|
||||
@@ -476,10 +495,11 @@ emitter_begin(emitter_t *emitter) {
|
||||
|
||||
static inline void
|
||||
emitter_end(emitter_t *emitter) {
|
||||
if (emitter->output == emitter_output_json) {
|
||||
if (emitter_outputs_json(emitter)) {
|
||||
assert(emitter->nesting_depth == 1);
|
||||
emitter_nest_dec(emitter);
|
||||
emitter_printf(emitter, "\n}\n");
|
||||
emitter_printf(emitter, "%s", emitter->output ==
|
||||
emitter_output_json_compact ? "}" : "\n}\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user