Skip to content

Proposal: struct json_object split

Eric Hawicz edited this page Jun 7, 2020 · 3 revisions

Originally mentioned in https://github.com/json-c/json-c/issues/535

if you really want to improve the overall memory usage, we should take advantage of the fact that json_object is a private, library-internal data structure, and split it into different structures for the different json types, and change the code to implement a polymorphic cast & dispatch approach based on that.

The rest of this page is meant to be a place to explore this idea more, before or while making changes to code.

See https://github.com/json-c/json-c/tree/json_object-split for changes, PR at https://github.com/json-c/json-c/pull/632

Any place we have things like "jso->p.c_string", etc... we instead do:

if (jso->o_type == json_type_string) {
    jso_str = (struct json_object_string *)jso;
   ...do stuff w/ jso_str...
}
etc...

Plus, define struct json_object_string to have "char data[1]" at the end, and have string data always be direct by allocating (sizeof(struct json_object_string) + strlen(s)).

struct json_object_base
{
  enum json_type o_type;
  uint32_t _ref_count;
  json_object_private_delete_fn *_delete;
  json_object_to_json_string_fn *_to_json_string;
  //struct printbuf *_pb;  (can probably be omitted from here)
  json_object_delete_fn *_user_delete;
  void *_userdata;
};

struct json_object_string
{
	struct json_object_base base;
	size_t len;
	// ... maybe add padding for alignment...
	char data[1];  // actually longer, at least len+1 bytes.
};
struct json_object_object
{
	struct json_object_base base;
	struct lh_table c_object; // note: not a pointer!
}
struct json_object_double
{
	struct json_object_base base;
	double c_double;
};
etc...