mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 22:35:15 +00:00
json: Use reference counting in JSON objects
After profiling OVSDB insert performance it was found that some significant portion of its time OVSDB is calling the function json_clone. Also, the current usages of json_clone never modify the json, just keeps it to prevent it to be freed. With that in mind the struct json, json_create, json_clone and json_destroy were modified to keep a count of how many references of the json struct are left. Only when that count reaches zero the json struct is freed. The old "json_clone" function was renamed as "json_deep_clone". Some examples of the performance difference: In these tests a test table with 4 columns (string, string, bool, integer) was used. All the tests used "commit block". *** 50 process each inserting 1000 rows *** Master OVS Test Duration 131 seconds Average Inserts Per second 746.2687 inserts/s Average Insert Duration 134.1382 ms Minimal Insert Duration 0.166202 ms Maximum Insert Duration 489.8593 ms JSON GC Patch Test Duration 86 seconds Average Inserts Per second 1176 inserts/s Average Insert Duration 82.26761 ms Minimal Insert Duration 0.165448 ms Maximum Insert Duration 751.2111 ms *** 5 process each inserting 10000 rows *** Master OVS Test Duration 8 seconds Average Inserts Per second 7142.857 inserts/s Average Insert Duration 0.656431 ms Minimal Insert Duration 0.125197 ms Maximum Insert Duration 11.93203 ms JSON GC Patch Test Duration 7 seconds Average Inserts Per second 8333.333 inserts/s Average Insert Duration 0.55688 ms Minimal Insert Duration 0.143233 ms Maximum Insert Duration 26.26319 ms Signed-off-by: Esteban Rodriguez Betancourt <estebarb@hpe.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
committed by
Ben Pfaff
parent
2e3cf773ea
commit
9854d473ad
@@ -63,6 +63,7 @@ struct json_array {
|
||||
/* A JSON value. */
|
||||
struct json {
|
||||
enum json_type type;
|
||||
size_t count;
|
||||
union {
|
||||
struct shash *object; /* Contains "struct json *"s. */
|
||||
struct json_array array;
|
||||
@@ -99,6 +100,7 @@ bool json_boolean(const struct json *);
|
||||
double json_real(const struct json *);
|
||||
int64_t json_integer(const struct json *);
|
||||
|
||||
struct json *json_deep_clone(const struct json *);
|
||||
struct json *json_clone(const struct json *);
|
||||
void json_destroy(struct json *);
|
||||
|
||||
|
18
lib/json.c
18
lib/json.c
@@ -333,7 +333,7 @@ static void json_destroy_array(struct json_array *array);
|
||||
void
|
||||
json_destroy(struct json *json)
|
||||
{
|
||||
if (json) {
|
||||
if (json && !--json->count) {
|
||||
switch (json->type) {
|
||||
case JSON_OBJECT:
|
||||
json_destroy_object(json->u.object);
|
||||
@@ -392,7 +392,7 @@ static struct json *json_clone_array(const struct json_array *array);
|
||||
|
||||
/* Returns a deep copy of 'json'. */
|
||||
struct json *
|
||||
json_clone(const struct json *json)
|
||||
json_deep_clone(const struct json *json)
|
||||
{
|
||||
switch (json->type) {
|
||||
case JSON_OBJECT:
|
||||
@@ -421,6 +421,15 @@ json_clone(const struct json *json)
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns 'json', with the reference count incremented. */
|
||||
struct json *
|
||||
json_clone(const struct json *json_)
|
||||
{
|
||||
struct json *json = CONST_CAST(struct json *, json_);
|
||||
json->count++;
|
||||
return json;
|
||||
}
|
||||
|
||||
static struct json *
|
||||
json_clone_object(const struct shash *object)
|
||||
{
|
||||
@@ -547,6 +556,10 @@ json_equal_array(const struct json_array *a, const struct json_array *b)
|
||||
bool
|
||||
json_equal(const struct json *a, const struct json *b)
|
||||
{
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a->type != b->type) {
|
||||
return false;
|
||||
}
|
||||
@@ -1405,6 +1418,7 @@ json_create(enum json_type type)
|
||||
{
|
||||
struct json *json = xmalloc(sizeof *json);
|
||||
json->type = type;
|
||||
json->count = 1;
|
||||
return json;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user