[ovs-dev] [PATCH] json: Use reference counting in json objects

Rodriguez Betancourt, Esteban estebarb at hpe.com
Tue Aug 16 21:50:37 UTC 2016


After profiling OVSDB insert performance it was found
that some significant portion of its time OVSDB is
calling the function json_clone.

Also, most of the 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".

The change provides some performance improvement, depending
on the transactions performed in OVSDB.

Signed-off-by: Esteban Rodriguez Betancourt <estebarb at hpe.com>
---
 lib/json.c | 18 ++++++++++++++++--
 lib/json.h |  2 ++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/lib/json.c b/lib/json.c
index 4ac250b..20909ed 100644
--- a/lib/json.c
+++ b/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);
@@ -390,9 +390,18 @@ json_destroy_array(struct json_array *array)
 static struct json *json_clone_object(const struct shash *object);
 static struct json *json_clone_array(const struct json_array *array);
 
+/* Increments the counter of the json instance */
+struct json *
+json_clone(const struct json *json_)
+{
+    struct json *json = CONST_CAST(struct json *, json_);
+    json->count++;
+    return json;
+}
+
 /* 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:
@@ -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;
 }
 
diff --git a/lib/json.h b/lib/json.h
index 3497035..a76c55d 100644
--- a/lib/json.h
+++ b/lib/json.h
@@ -61,6 +61,7 @@ struct json_array {
 
 /* A JSON value. */
 struct json {
+    size_t count;
     enum json_type type;
     union {
         struct shash *object;   /* Contains "struct json *"s. */
@@ -99,6 +100,7 @@ double json_real(const struct json *);
 int64_t json_integer(const struct json *);
 
 struct json *json_clone(const struct json *);
+struct json *json_deep_clone(const struct json *);
 void json_destroy(struct json *);
 
 size_t json_hash(const struct json *, size_t basis);
-- 
2.7.4



More information about the dev mailing list