mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-12 10:30:29 +01:00
common/json: only maintain array of nested types if DEVELOPER mode.
My test case is a mainnet gossip store with 22107 channels, and time to do `lightning-cli listchannels`: Before: `lightning-cli listchannels` DEVELOPER=0 real 0m1.396000-1.409000(1.4022+/-0.005)s After: real 0m1.307000-1.320000(1.3128+/-0.005)s Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
20bed28759
commit
8238fe6acf
3 changed files with 47 additions and 26 deletions
|
@ -4,6 +4,7 @@ LIGHTNING_CLI_OBJS := $(LIGHTNING_CLI_SRC:.c=.o)
|
||||||
LIGHTNING_CLI_COMMON_OBJS := \
|
LIGHTNING_CLI_COMMON_OBJS := \
|
||||||
common/configdir.o \
|
common/configdir.o \
|
||||||
common/json.o \
|
common/json.o \
|
||||||
|
common/memleak.o \
|
||||||
common/utils.o \
|
common/utils.o \
|
||||||
common/version.o
|
common/version.o
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <ccan/tal/str/str.h>
|
#include <ccan/tal/str/str.h>
|
||||||
#include <common/configdir.h>
|
#include <common/configdir.h>
|
||||||
#include <common/json.h>
|
#include <common/json.h>
|
||||||
|
#include <common/memleak.h>
|
||||||
#include <common/utils.h>
|
#include <common/utils.h>
|
||||||
#include <common/version.h>
|
#include <common/version.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <ccan/str/hex/hex.h>
|
#include <ccan/str/hex/hex.h>
|
||||||
#include <ccan/tal/str/str.h>
|
#include <ccan/tal/str/str.h>
|
||||||
#include <common/json.h>
|
#include <common/json.h>
|
||||||
|
#include <common/memleak.h>
|
||||||
#include <common/type_to_string.h>
|
#include <common/type_to_string.h>
|
||||||
#include <common/wireaddr.h>
|
#include <common/wireaddr.h>
|
||||||
#include <gossipd/routing.h>
|
#include <gossipd/routing.h>
|
||||||
|
@ -480,8 +481,12 @@ bool json_tok_tok(struct command *cmd, const char *name,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct json_result {
|
struct json_result {
|
||||||
|
#if DEVELOPER
|
||||||
/* tal_arr of types (JSMN_OBJECT/JSMN_ARRAY) we're enclosed in. */
|
/* tal_arr of types (JSMN_OBJECT/JSMN_ARRAY) we're enclosed in. */
|
||||||
jsmntype_t *wrapping;
|
jsmntype_t *wrapping;
|
||||||
|
#endif
|
||||||
|
/* How far to indent. */
|
||||||
|
size_t indent;
|
||||||
|
|
||||||
/* True if we haven't yet put an element in current wrapping */
|
/* True if we haven't yet put an element in current wrapping */
|
||||||
bool empty;
|
bool empty;
|
||||||
|
@ -517,6 +522,7 @@ result_append_fmt(struct json_result *res, const char *fmt, ...)
|
||||||
static void check_fieldname(const struct json_result *result,
|
static void check_fieldname(const struct json_result *result,
|
||||||
const char *fieldname)
|
const char *fieldname)
|
||||||
{
|
{
|
||||||
|
#if DEVELOPER
|
||||||
size_t n = tal_count(result->wrapping);
|
size_t n = tal_count(result->wrapping);
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
/* Can't have a fieldname if not in anything! */
|
/* Can't have a fieldname if not in anything! */
|
||||||
|
@ -527,9 +533,22 @@ static void check_fieldname(const struct json_result *result,
|
||||||
else
|
else
|
||||||
/* Must have fieldnames in objects. */
|
/* Must have fieldnames in objects. */
|
||||||
assert(fieldname);
|
assert(fieldname);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void result_add_indent(struct json_result *result);
|
static void result_append_indent(struct json_result *result)
|
||||||
|
{
|
||||||
|
static const char indent_buf[] = " ";
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < result->indent * 2; i += len) {
|
||||||
|
len = result->indent * 2;
|
||||||
|
if (len > sizeof(indent_buf)-1)
|
||||||
|
len = sizeof(indent_buf)-1;
|
||||||
|
/* Use tail of indent_buf string. */
|
||||||
|
result_append(result, indent_buf + sizeof(indent_buf) - 1 - len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void json_start_member(struct json_result *result, const char *fieldname)
|
static void json_start_member(struct json_result *result, const char *fieldname)
|
||||||
{
|
{
|
||||||
|
@ -539,7 +558,7 @@ static void json_start_member(struct json_result *result, const char *fieldname)
|
||||||
else
|
else
|
||||||
result_append(result, "\n");
|
result_append(result, "\n");
|
||||||
|
|
||||||
result_add_indent(result);
|
result_append_indent(result);
|
||||||
|
|
||||||
check_fieldname(result, fieldname);
|
check_fieldname(result, fieldname);
|
||||||
if (fieldname)
|
if (fieldname)
|
||||||
|
@ -547,45 +566,39 @@ static void json_start_member(struct json_result *result, const char *fieldname)
|
||||||
result->empty = false;
|
result->empty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void result_add_indent(struct json_result *result)
|
static void result_indent(struct json_result *result, jsmntype_t type)
|
||||||
{
|
|
||||||
size_t i, indent = tal_count(result->wrapping);
|
|
||||||
|
|
||||||
if (!indent)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < indent; i++)
|
|
||||||
result_append(result, " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void result_add_wrap(struct json_result *result, jsmntype_t type)
|
|
||||||
{
|
{
|
||||||
|
#if DEVELOPER
|
||||||
*tal_arr_expand(&result->wrapping) = type;
|
*tal_arr_expand(&result->wrapping) = type;
|
||||||
|
#endif
|
||||||
result->empty = true;
|
result->empty = true;
|
||||||
|
result->indent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void result_pop_wrap(struct json_result *result, jsmntype_t type)
|
static void result_unindent(struct json_result *result, jsmntype_t type)
|
||||||
{
|
{
|
||||||
size_t indent = tal_count(result->wrapping);
|
assert(result->indent);
|
||||||
|
#if DEVELOPER
|
||||||
assert(indent);
|
assert(tal_count(result->wrapping) == result->indent);
|
||||||
assert(result->wrapping[indent-1] == type);
|
assert(result->wrapping[result->indent-1] == type);
|
||||||
tal_resize(&result->wrapping, indent-1);
|
tal_resize(&result->wrapping, result->indent-1);
|
||||||
|
#endif
|
||||||
result->empty = false;
|
result->empty = false;
|
||||||
|
result->indent--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void json_array_start(struct json_result *result, const char *fieldname)
|
void json_array_start(struct json_result *result, const char *fieldname)
|
||||||
{
|
{
|
||||||
json_start_member(result, fieldname);
|
json_start_member(result, fieldname);
|
||||||
result_append(result, "[");
|
result_append(result, "[");
|
||||||
result_add_wrap(result, JSMN_ARRAY);
|
result_indent(result, JSMN_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void json_array_end(struct json_result *result)
|
void json_array_end(struct json_result *result)
|
||||||
{
|
{
|
||||||
result_append(result, "\n");
|
result_append(result, "\n");
|
||||||
result_pop_wrap(result, JSMN_ARRAY);
|
result_unindent(result, JSMN_ARRAY);
|
||||||
result_add_indent(result);
|
result_append_indent(result);
|
||||||
result_append(result, "]");
|
result_append(result, "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,14 +606,14 @@ void json_object_start(struct json_result *result, const char *fieldname)
|
||||||
{
|
{
|
||||||
json_start_member(result, fieldname);
|
json_start_member(result, fieldname);
|
||||||
result_append(result, "{");
|
result_append(result, "{");
|
||||||
result_add_wrap(result, JSMN_OBJECT);
|
result_indent(result, JSMN_OBJECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void json_object_end(struct json_result *result)
|
void json_object_end(struct json_result *result)
|
||||||
{
|
{
|
||||||
result_append(result, "\n");
|
result_append(result, "\n");
|
||||||
result_pop_wrap(result, JSMN_OBJECT);
|
result_unindent(result, JSMN_OBJECT);
|
||||||
result_add_indent(result);
|
result_append_indent(result);
|
||||||
result_append(result, "}");
|
result_append(result, "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,14 +708,20 @@ struct json_result *new_json_result(const tal_t *ctx)
|
||||||
struct json_result *r = tal(ctx, struct json_result);
|
struct json_result *r = tal(ctx, struct json_result);
|
||||||
|
|
||||||
r->s = tal_strdup(r, "");
|
r->s = tal_strdup(r, "");
|
||||||
|
#if DEVELOPER
|
||||||
r->wrapping = tal_arr(r, jsmntype_t, 0);
|
r->wrapping = tal_arr(r, jsmntype_t, 0);
|
||||||
|
#endif
|
||||||
|
r->indent = 0;
|
||||||
r->empty = true;
|
r->empty = true;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *json_result_string(const struct json_result *result)
|
const char *json_result_string(const struct json_result *result)
|
||||||
{
|
{
|
||||||
|
#if DEVELOPER
|
||||||
assert(tal_count(result->wrapping) == 0);
|
assert(tal_count(result->wrapping) == 0);
|
||||||
|
#endif
|
||||||
|
assert(result->indent == 0);
|
||||||
assert(tal_count(result->s) == strlen(result->s) + 1);
|
assert(tal_count(result->s) == strlen(result->s) + 1);
|
||||||
return result->s;
|
return result->s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue