Browse Source

add json_object_object_add_ex() API

This provides more control over some detail aspects, many
of which are performance related.
tags/json-c-0.13-20171207
Rainer Gerhards 10 years ago
parent
commit
2d549662be
4 changed files with 80 additions and 5 deletions
  1. +28
    -2
      json_object.c
  2. +46
    -0
      json_object.h
  3. +3
    -2
      linkhash.c
  4. +3
    -1
      linkhash.h

+ 28
- 2
json_object.c View File

@@ -355,7 +355,8 @@ static int json_object_object_to_json_string(struct json_object* jso,

static void json_object_lh_entry_free(struct lh_entry *ent)
{
free(ent->k);
if (!ent->k_is_constant)
free(ent->k);
json_object_put((struct json_object*)ent->v);
}

@@ -396,6 +397,31 @@ struct lh_table* json_object_get_object(struct json_object *jso)
}
}

void json_object_object_add_ex(struct json_object* jso,
const char *const key,
struct json_object *const val,
const unsigned opts)
{
// We lookup the entry and replace the value, rather than just deleting
// and re-adding it, so the existing key remains valid.
json_object *existing_value = NULL;
struct lh_entry *existing_entry;
const unsigned long hash = lh_get_hash(jso->o.c_object, (void*)key);
existing_entry = (opts & JSON_C_OBJECT_ADD_KEY_IS_NEW) ? NULL :
lh_table_lookup_entry_w_hash(jso->o.c_object, (void*)key, hash);
if (!existing_entry)
{
void *const k = (opts & JSON_C_OBJECT_KEY_IS_CONSTANT) ?
(void*)key : strdup(key);
lh_table_insert_w_hash(jso->o.c_object, k, val, hash, opts);
return;
}
existing_value = (void *)existing_entry->v;
if (existing_value)
json_object_put(existing_value);
existing_entry->v = val;
}

void json_object_object_add(struct json_object* jso, const char *key,
struct json_object *val)
{
@@ -407,7 +433,7 @@ void json_object_object_add(struct json_object* jso, const char *key,
existing_entry = lh_table_lookup_entry_w_hash(jso->o.c_object, (void*)key, hash);
if (!existing_entry)
{
lh_table_insert_w_hash(jso->o.c_object, strdup(key), val, hash);
lh_table_insert_w_hash(jso->o.c_object, strdup(key), val, hash, 0);
return;
}
existing_value = (void *)existing_entry->v;


+ 46
- 0
json_object.h View File

@@ -55,6 +55,36 @@ extern "C" {
*/
#define JSON_C_TO_STRING_NOZERO (1<<2)

/**
* A flag for the json_object_object_add_ex function which
* causes the value to be added without a check if it already exists.
* Note: it is the responsibilty of the caller to ensure that no
* key is added multiple times. If this is done, results are
* unpredictable. While this option is somewhat dangerous, it
* permits potentially large performance savings in code that
* knows for sure the key values are unique (e.g. because the
* code adds a well-known set of constant key values).
*/
#define JSON_C_OBJECT_ADD_KEY_IS_NEW (1<<1)
/**
* A flag for the json_object_object_add_ex function which
* flags the key as being constant memory. This means that
* the key will NOT be copied via strdup(), resulting in a
* potentially huge performance win (malloc, strdup and
* free are usually performance hogs). It is acceptable to
* use this flag for keys in non-constant memory blocks if
* the caller ensure that the memory holding the key lives
* longer than the corresponding json object. However, this
* is somewhat dangerous and should only be done if really
* justified.
* The general use-case for this flag is cases where the
* key is given as a real constant value in the function
* call, e.g. as in
* json_object_object_add_ex(obj, "ip", json,
* JSON_C_OBJECT_KEY_IS_CONSTANT);
*/
#define JSON_C_OBJECT_KEY_IS_CONSTANT (1<<2)

#undef FALSE
#define FALSE ((json_bool)0)

@@ -275,6 +305,22 @@ extern int json_object_object_length(struct json_object* obj);
extern void json_object_object_add(struct json_object* obj, const char *key,
struct json_object *val);

/** Add an object field to a json_object of type json_type_object
*
* The semantics are identical to json_object_object_add, except that an
* additional flag fields gives you more control over some detail aspects
* of processing. See the description of JSON_C_OBJECT_ADD_* flags for more
* details.
*
* @param obj the json_object instance
* @param key the object field name (a private copy will be duplicated)
* @param val a json_object or NULL member to associate with the given field
* @param opts process-modifying options. To specify multiple options, use
* arithmetic or (OPT1|OPT2)
*/
extern void json_object_object_add_ex(struct json_object* obj, const char *key,
struct json_object *val, const unsigned opts);

/** Get the json_object associate with a given object field
*
* *No* reference counts will be changed. There is no need to manually adjust


+ 3
- 2
linkhash.c View File

@@ -490,7 +490,7 @@ void lh_table_free(struct lh_table *t)
}


int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const unsigned long h)
int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const unsigned long h, const unsigned opts)
{
unsigned long n;

@@ -506,6 +506,7 @@ int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const uns
}

t->table[n].k = k;
t->table[n].k_is_constant = (opts & JSON_C_OBJECT_KEY_IS_CONSTANT);
t->table[n].v = v;
t->count++;

@@ -523,7 +524,7 @@ int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const uns
}
int lh_table_insert(struct lh_table *t, void *k, const void *v)
{
return lh_table_insert_w_hash(t, k, v, lh_get_hash(t, k));
return lh_table_insert_w_hash(t, k, v, lh_get_hash(t, k), 0);
}




+ 3
- 1
linkhash.h View File

@@ -64,6 +64,7 @@ struct lh_entry {
* The key.
*/
void *k;
int k_is_constant;
/**
* The value.
*/
@@ -241,8 +242,9 @@ extern int lh_table_insert(struct lh_table *t, void *k, const void *v);
* @param k a pointer to the key to insert.
* @param v a pointer to the value to insert.
* @param h hash value of the key to insert
* @param opts opts, a subset of JSON_OBJECT_ADD_* flags is supported
*/
extern int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const unsigned long h);
extern int lh_table_insert_w_hash(struct lh_table *t, void *k, const void *v, const unsigned long h, const unsigned opts);


/**


Loading…
Cancel
Save