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:
Yinan Zhang
2019-07-30 11:07:24 -07:00
parent 7fc6b1b259
commit 8c8466fa6e
2 changed files with 160 additions and 76 deletions

View File

@@ -66,7 +66,9 @@ forwarding_cb(void *buf_descriptor_v, const char *str) {
static void
assert_emit_output(void (*emit_fn)(emitter_t *),
const char *expected_json_output, const char *expected_table_output) {
const char *expected_json_output,
const char *expected_json_compact_output,
const char *expected_table_output) {
emitter_t emitter;
char buf[MALLOC_PRINTF_BUFSIZE];
buf_descriptor_t buf_descriptor;
@@ -84,6 +86,16 @@ assert_emit_output(void (*emit_fn)(emitter_t *),
buf_descriptor.len = MALLOC_PRINTF_BUFSIZE;
buf_descriptor.mid_quote = false;
emitter_init(&emitter, emitter_output_json_compact, &forwarding_cb,
&buf_descriptor);
(*emit_fn)(&emitter);
assert_str_eq(expected_json_compact_output, buf,
"compact json output failure");
buf_descriptor.buf = buf;
buf_descriptor.len = MALLOC_PRINTF_BUFSIZE;
buf_descriptor.mid_quote = false;
emitter_init(&emitter, emitter_output_table, &forwarding_cb,
&buf_descriptor);
(*emit_fn)(&emitter);
@@ -108,6 +120,7 @@ emit_dict(emitter_t *emitter) {
emitter_dict_end(emitter);
emitter_end(emitter);
}
static const char *dict_json =
"{\n"
"\t\"foo\": {\n"
@@ -117,6 +130,15 @@ static const char *dict_json =
"\t\t\"jkl\": \"a string\"\n"
"\t}\n"
"}\n";
static const char *dict_json_compact =
"{"
"\"foo\":{"
"\"abc\":false,"
"\"def\":true,"
"\"ghi\":123,"
"\"jkl\":\"a string\""
"}"
"}";
static const char *dict_table =
"This is the foo table:\n"
" ABC: false\n"
@@ -124,11 +146,6 @@ static const char *dict_table =
" GHI: 123 (note_key1: \"a string\")\n"
" JKL: \"a string\" (note_key2: false)\n";
TEST_BEGIN(test_dict) {
assert_emit_output(&emit_dict, dict_json, dict_table);
}
TEST_END
static void
emit_table_printf(emitter_t *emitter) {
emitter_begin(emitter);
@@ -141,17 +158,11 @@ emit_table_printf(emitter_t *emitter) {
static const char *table_printf_json =
"{\n"
"}\n";
static const char *table_printf_json_compact = "{}";
static const char *table_printf_table =
"Table note 1\n"
"Table note 2 with format string\n";
TEST_BEGIN(test_table_printf) {
assert_emit_output(&emit_table_printf, table_printf_json,
table_printf_table);
}
TEST_END
static void emit_nested_dict(emitter_t *emitter) {
int val = 123;
emitter_begin(emitter);
@@ -169,7 +180,7 @@ static void emit_nested_dict(emitter_t *emitter) {
emitter_end(emitter);
}
static const char *nested_object_json =
static const char *nested_dict_json =
"{\n"
"\t\"json1\": {\n"
"\t\t\"json2\": {\n"
@@ -182,8 +193,20 @@ static const char *nested_object_json =
"\t\t\"primitive\": 123\n"
"\t}\n"
"}\n";
static const char *nested_object_table =
static const char *nested_dict_json_compact =
"{"
"\"json1\":{"
"\"json2\":{"
"\"primitive\":123"
"},"
"\"json3\":{"
"}"
"},"
"\"json4\":{"
"\"primitive\":123"
"}"
"}";
static const char *nested_dict_table =
"Dict 1\n"
" Dict 2\n"
" A primitive: 123\n"
@@ -191,12 +214,6 @@ static const char *nested_object_table =
"Dict 4\n"
" Another primitive: 123\n";
TEST_BEGIN(test_nested_dict) {
assert_emit_output(&emit_nested_dict, nested_object_json,
nested_object_table);
}
TEST_END
static void
emit_types(emitter_t *emitter) {
bool b = false;
@@ -235,7 +252,17 @@ static const char *types_json =
"\t\"k7\": 789,\n"
"\t\"k8\": 10000000000\n"
"}\n";
static const char *types_json_compact =
"{"
"\"k1\":false,"
"\"k2\":-123,"
"\"k3\":123,"
"\"k4\":-456,"
"\"k5\":456,"
"\"k6\":\"string\","
"\"k7\":789,"
"\"k8\":10000000000"
"}";
static const char *types_table =
"K1: false\n"
"K2: -123\n"
@@ -246,11 +273,6 @@ static const char *types_table =
"K7: 789\n"
"K8: 10000000000\n";
TEST_BEGIN(test_types) {
assert_emit_output(&emit_types, types_json, types_table);
}
TEST_END
static void
emit_modal(emitter_t *emitter) {
int val = 123;
@@ -283,7 +305,18 @@ const char *modal_json =
"\t\t\"i6\": 123\n"
"\t}\n"
"}\n";
const char *modal_json_compact =
"{"
"\"j0\":{"
"\"j1\":{"
"\"i1\":123,"
"\"i2\":123,"
"\"i4\":123"
"},"
"\"i5\":123,"
"\"i6\":123"
"}"
"}";
const char *modal_table =
"T0\n"
" I1: 123\n"
@@ -293,13 +326,8 @@ const char *modal_table =
" I5: 123\n"
" I6: 123\n";
TEST_BEGIN(test_modal) {
assert_emit_output(&emit_modal, modal_json, modal_table);
}
TEST_END
static void
emit_json_arr(emitter_t *emitter) {
emit_json_array(emitter_t *emitter) {
int ival = 123;
emitter_begin(emitter);
@@ -338,14 +366,24 @@ static const char *json_array_json =
"\t\t]\n"
"\t}\n"
"}\n";
static const char *json_array_json_compact =
"{"
"\"dict\":{"
"\"arr\":["
"{"
"\"foo\":123"
"},"
"123,"
"123,"
"{"
"\"bar\":123,"
"\"baz\":123"
"}"
"]"
"}"
"}";
static const char *json_array_table = "";
TEST_BEGIN(test_json_arr) {
assert_emit_output(&emit_json_arr, json_array_json, json_array_table);
}
TEST_END
static void
emit_json_nested_array(emitter_t *emitter) {
int ival = 123;
@@ -391,12 +429,27 @@ static const char *json_nested_array_json =
"\t\t]\n"
"\t]\n"
"}\n";
TEST_BEGIN(test_json_nested_arr) {
assert_emit_output(&emit_json_nested_array, json_nested_array_json,
json_array_table);
}
TEST_END
static const char *json_nested_array_json_compact =
"{"
"["
"["
"123,"
"\"foo\","
"123,"
"\"foo\""
"],"
"["
"123"
"],"
"["
"\"foo\","
"123"
"],"
"["
"]"
"]"
"}";
static const char *json_nested_array_table = "";
static void
emit_table_row(emitter_t *emitter) {
@@ -443,18 +496,29 @@ emit_table_row(emitter_t *emitter) {
static const char *table_row_json =
"{\n"
"}\n";
static const char *table_row_json_compact = "{}";
static const char *table_row_table =
"ABC title DEF title GHI\n"
"123 true 456\n"
"789 false 1011\n"
"\"a string\" false ghi\n";
TEST_BEGIN(test_table_row) {
assert_emit_output(&emit_table_row, table_row_json, table_row_table);
}
#define GENERATE_TEST(feature) \
TEST_BEGIN(test_##feature) { \
assert_emit_output(emit_##feature, feature##_json, \
feature##_json_compact, feature##_table); \
} \
TEST_END
GENERATE_TEST(dict)
GENERATE_TEST(table_printf)
GENERATE_TEST(nested_dict)
GENERATE_TEST(types)
GENERATE_TEST(modal)
GENERATE_TEST(json_array)
GENERATE_TEST(json_nested_array)
GENERATE_TEST(table_row)
int
main(void) {
return test_no_reentrancy(
@@ -463,7 +527,7 @@ main(void) {
test_nested_dict,
test_types,
test_modal,
test_json_arr,
test_json_nested_arr,
test_json_array,
test_json_nested_array,
test_table_row);
}