Bump hashtable, allocate object->hashtable statically
Hashtable code from git://github.com/akheron/hashtable.git commit 7331ba6acdb415a2af62ae3e93fdd39c2a83b768
This commit is contained in:
parent
a2adf6ec98
commit
61d0111323
@ -8,40 +8,15 @@
|
||||
#include <stdlib.h>
|
||||
#include "hashtable.h"
|
||||
|
||||
typedef struct hashtable_list list_t;
|
||||
typedef struct hashtable_pair pair_t;
|
||||
typedef struct hashtable_bucket bucket_t;
|
||||
|
||||
#define container_of(ptr_, type_, member_) \
|
||||
((type_ *)((char *)ptr_ - (size_t)&((type_ *)0)->member_))
|
||||
|
||||
typedef struct list_t {
|
||||
struct list_t *prev;
|
||||
struct list_t *next;
|
||||
} list_t;
|
||||
|
||||
typedef struct {
|
||||
void *key;
|
||||
void *value;
|
||||
unsigned int hash;
|
||||
list_t list;
|
||||
} pair_t;
|
||||
|
||||
#define list_to_pair(list_) container_of(list_, pair_t, list)
|
||||
|
||||
typedef struct {
|
||||
list_t *first;
|
||||
list_t *last;
|
||||
} bucket_t;
|
||||
|
||||
struct hashtable {
|
||||
unsigned int size;
|
||||
bucket_t *buckets;
|
||||
unsigned int num_buckets; /* index to primes[] */
|
||||
list_t list;
|
||||
|
||||
key_hash_fn hash_key;
|
||||
key_cmp_fn cmp_keys; /* returns non-zero for equal keys */
|
||||
free_fn free_key;
|
||||
free_fn free_value;
|
||||
};
|
||||
|
||||
static inline void list_init(list_t *list)
|
||||
{
|
||||
list->next = list;
|
||||
@ -193,22 +168,40 @@ static int hashtable_do_rehash(hashtable_t *hashtable)
|
||||
}
|
||||
|
||||
|
||||
hashtable_t *hashtable_new(key_hash_fn hash_key, key_cmp_fn cmp_keys,
|
||||
free_fn free_key, free_fn free_value)
|
||||
hashtable_t *hashtable_create(key_hash_fn hash_key, key_cmp_fn cmp_keys,
|
||||
free_fn free_key, free_fn free_value)
|
||||
{
|
||||
unsigned int i;
|
||||
hashtable_t *hashtable = malloc(sizeof(hashtable_t));
|
||||
if(!hashtable)
|
||||
return NULL;
|
||||
|
||||
if(hashtable_init(hashtable, hash_key, cmp_keys, free_key, free_value))
|
||||
{
|
||||
free(hashtable);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return hashtable;
|
||||
}
|
||||
|
||||
void hashtable_destroy(hashtable_t *hashtable)
|
||||
{
|
||||
hashtable_close(hashtable);
|
||||
free(hashtable);
|
||||
}
|
||||
|
||||
int hashtable_init(hashtable_t *hashtable,
|
||||
key_hash_fn hash_key, key_cmp_fn cmp_keys,
|
||||
free_fn free_key, free_fn free_value)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
hashtable->size = 0;
|
||||
hashtable->num_buckets = 0; /* index to primes[] */
|
||||
hashtable->buckets = malloc(num_buckets(hashtable) * sizeof(bucket_t));
|
||||
if(!hashtable->buckets)
|
||||
{
|
||||
free(hashtable);
|
||||
return NULL;
|
||||
}
|
||||
return -1;
|
||||
|
||||
list_init(&hashtable->list);
|
||||
|
||||
hashtable->hash_key = hash_key;
|
||||
@ -222,10 +215,10 @@ hashtable_t *hashtable_new(key_hash_fn hash_key, key_cmp_fn cmp_keys,
|
||||
&hashtable->list;
|
||||
}
|
||||
|
||||
return hashtable;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hashtable_free(hashtable_t *hashtable)
|
||||
void hashtable_close(hashtable_t *hashtable)
|
||||
{
|
||||
list_t *list, *next;
|
||||
pair_t *pair;
|
||||
@ -241,7 +234,6 @@ void hashtable_free(hashtable_t *hashtable)
|
||||
}
|
||||
|
||||
free(hashtable->buckets);
|
||||
free(hashtable);
|
||||
}
|
||||
|
||||
int hashtable_set(hashtable_t *hashtable, void *key, void *value)
|
||||
@ -267,11 +259,11 @@ int hashtable_set(hashtable_t *hashtable, void *key, void *value)
|
||||
pair->key = key;
|
||||
pair->value = value;
|
||||
pair->hash = hash;
|
||||
list_init(&pair->list);
|
||||
|
||||
index = hash % num_buckets(hashtable);
|
||||
bucket = &hashtable->buckets[index];
|
||||
|
||||
list_init(&pair->list);
|
||||
insert_to_bucket(hashtable, bucket, &pair->list);
|
||||
|
||||
hashtable->size++;
|
||||
|
@ -8,14 +8,41 @@
|
||||
#ifndef HASHTABLE_H
|
||||
#define HASHTABLE_H
|
||||
|
||||
typedef struct hashtable hashtable_t;
|
||||
|
||||
typedef unsigned int (*key_hash_fn)(const void *key);
|
||||
typedef int (*key_cmp_fn)(const void *key1, const void *key2);
|
||||
typedef void (*free_fn)(void *key);
|
||||
|
||||
struct hashtable_list {
|
||||
struct hashtable_list *prev;
|
||||
struct hashtable_list *next;
|
||||
};
|
||||
|
||||
struct hashtable_pair {
|
||||
void *key;
|
||||
void *value;
|
||||
unsigned int hash;
|
||||
struct hashtable_list list;
|
||||
};
|
||||
|
||||
struct hashtable_bucket {
|
||||
struct hashtable_list *first;
|
||||
struct hashtable_list *last;
|
||||
};
|
||||
|
||||
typedef struct hashtable {
|
||||
unsigned int size;
|
||||
struct hashtable_bucket *buckets;
|
||||
unsigned int num_buckets; /* index to primes[] */
|
||||
struct hashtable_list list;
|
||||
|
||||
key_hash_fn hash_key;
|
||||
key_cmp_fn cmp_keys; /* returns non-zero for equal keys */
|
||||
free_fn free_key;
|
||||
free_fn free_value;
|
||||
} hashtable_t;
|
||||
|
||||
/**
|
||||
* hashtable_new - Create a hashtable object
|
||||
* hashtable_create - Create a hashtable object
|
||||
*
|
||||
* @hash_key: The key hashing function
|
||||
* @cmp_keys: The key compare function. Returns non-zero for equal and
|
||||
@ -24,17 +51,48 @@ typedef void (*free_fn)(void *key);
|
||||
* @free_value: If non-NULL, called for a value that is no longer referenced.
|
||||
*
|
||||
* Returns a new hashtable object that should be freed with
|
||||
* hashtable_free when it's no longer used.
|
||||
* hashtable_destroy when it's no longer used, or NULL on failure (out
|
||||
* of memory).
|
||||
*/
|
||||
hashtable_t *hashtable_new(key_hash_fn hash_key, key_cmp_fn cmp_keys,
|
||||
free_fn free_key, free_fn free_value);
|
||||
hashtable_t *hashtable_create(key_hash_fn hash_key, key_cmp_fn cmp_keys,
|
||||
free_fn free_key, free_fn free_value);
|
||||
|
||||
/**
|
||||
* hashtable_free - Destroy a hashtable object
|
||||
* hashtable_destroy - Destroy a hashtable object
|
||||
*
|
||||
* @hashtable: The hashtable
|
||||
*
|
||||
* Destroys a hashtable created with hashtable_create().
|
||||
*/
|
||||
void hashtable_free(hashtable_t *hashtable);
|
||||
void hashtable_destroy(hashtable_t *hashtable);
|
||||
|
||||
/**
|
||||
* hashtable_init - Initialize a hashtable object
|
||||
*
|
||||
* @hashtable: The (statically allocated) hashtable object
|
||||
* @hash_key: The key hashing function
|
||||
* @cmp_keys: The key compare function. Returns non-zero for equal and
|
||||
* zero for unequal unequal keys
|
||||
* @free_key: If non-NULL, called for a key that is no longer referenced.
|
||||
* @free_value: If non-NULL, called for a value that is no longer referenced.
|
||||
*
|
||||
* Initializes a statically allocated hashtable object. The object
|
||||
* should be cleared with hashtable_close when it's no longer used.
|
||||
*
|
||||
* Returns 0 on success, -1 on error (out of memory).
|
||||
*/
|
||||
int hashtable_init(hashtable_t *hashtable,
|
||||
key_hash_fn hash_key, key_cmp_fn cmp_keys,
|
||||
free_fn free_key, free_fn free_value);
|
||||
|
||||
/**
|
||||
* hashtable_close - Release all resources used by a hashtable object
|
||||
*
|
||||
* @hashtable: The hashtable
|
||||
*
|
||||
* Destroys a statically allocated hashtable object.
|
||||
*/
|
||||
void hashtable_close(hashtable_t *hashtable);
|
||||
|
||||
/**
|
||||
* hashtable_set - Add/modify value in hashtable
|
||||
|
19
src/value.c
19
src/value.c
@ -12,7 +12,7 @@
|
||||
|
||||
typedef struct {
|
||||
json_t json;
|
||||
hashtable_t *hashtable;
|
||||
hashtable_t hashtable;
|
||||
} json_object_t;
|
||||
|
||||
typedef struct {
|
||||
@ -78,9 +78,8 @@ json_t *json_object(void)
|
||||
return NULL;
|
||||
json_init(&object->json, JSON_OBJECT);
|
||||
|
||||
object->hashtable =
|
||||
hashtable_new(hash_string, string_equal, free, value_decref);
|
||||
if(!object->hashtable)
|
||||
if(hashtable_init(&object->hashtable, hash_string, string_equal,
|
||||
free, value_decref))
|
||||
{
|
||||
free(object);
|
||||
return NULL;
|
||||
@ -90,7 +89,7 @@ json_t *json_object(void)
|
||||
|
||||
static void json_delete_object(json_object_t *object)
|
||||
{
|
||||
hashtable_free(object->hashtable);
|
||||
hashtable_close(&object->hashtable);
|
||||
free(object);
|
||||
}
|
||||
|
||||
@ -101,7 +100,7 @@ json_t *json_object_get(const json_t *json, const char *key)
|
||||
if(!json_is_object(json))
|
||||
return NULL;
|
||||
|
||||
return hashtable_get(object->hashtable, key);
|
||||
return hashtable_get(&object->hashtable, key);
|
||||
}
|
||||
|
||||
int json_object_set(json_t *json, const char *key, json_t *value)
|
||||
@ -112,7 +111,7 @@ int json_object_set(json_t *json, const char *key, json_t *value)
|
||||
return -1;
|
||||
|
||||
object = json_to_object(json);
|
||||
return hashtable_set(object->hashtable, strdup(key), json_incref(value));
|
||||
return hashtable_set(&object->hashtable, strdup(key), json_incref(value));
|
||||
}
|
||||
|
||||
int json_object_del(json_t *json, const char *key)
|
||||
@ -123,7 +122,7 @@ int json_object_del(json_t *json, const char *key)
|
||||
return -1;
|
||||
|
||||
object = json_to_object(json);
|
||||
return hashtable_del(object->hashtable, key);
|
||||
return hashtable_del(&object->hashtable, key);
|
||||
}
|
||||
|
||||
void *json_object_iter(json_t *json)
|
||||
@ -134,7 +133,7 @@ void *json_object_iter(json_t *json)
|
||||
return NULL;
|
||||
|
||||
object = json_to_object(json);
|
||||
return hashtable_iter(object->hashtable);
|
||||
return hashtable_iter(&object->hashtable);
|
||||
}
|
||||
|
||||
void *json_object_iter_next(json_t *json, void *iter)
|
||||
@ -145,7 +144,7 @@ void *json_object_iter_next(json_t *json, void *iter)
|
||||
return NULL;
|
||||
|
||||
object = json_to_object(json);
|
||||
return hashtable_iter_next(object->hashtable, iter);
|
||||
return hashtable_iter_next(&object->hashtable, iter);
|
||||
}
|
||||
|
||||
const char *json_object_iter_key(void *iter)
|
||||
|
Loading…
Reference in New Issue
Block a user