From 7fcead4473bc224bc8c6a66e2db3b3ee87f751d4 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Wed, 25 Jan 2006 04:07:04 +0000 Subject: Configuration file parsing for rrdbotd. --- src/common/hash.c | 53 +++++++++++++++++++++++++++++++++-------------------- src/common/hash.h | 30 ++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 28 deletions(-) (limited to 'src/common') diff --git a/src/common/hash.c b/src/common/hash.c index eb48c88..789e85c 100644 --- a/src/common/hash.c +++ b/src/common/hash.c @@ -55,7 +55,7 @@ #include #include "hash.h" -#define KEY_DATA(he) (void*)(((unsigned char*)(he)) + sizeof(*(he))) +#define KEY_DATA(he) ((he)->key) /* * The internal form of a hash table. @@ -72,6 +72,8 @@ struct hsh_entry_t { hsh_entry_t* next; unsigned int hash; + const void* key; + size_t klen; const void* val; }; @@ -103,25 +105,24 @@ struct hsh_t hsh_index_t iterator; /* For hsh_first(...) */ unsigned int count; unsigned int max; - unsigned int klen; }; #define INITIAL_MAX 15 /* tunable == 2^n - 1 */ #define int_malloc malloc +#define int_calloc calloc #define int_free free - /* * Hash creation functions. */ static hsh_entry_t** alloc_array(hsh_t* ht, unsigned int max) { - return int_calloc(sizeof(*(ht->array)) * (max + 1)); + return (hsh_entry_t**)int_calloc(sizeof(*(ht->array)), (max + 1)); } -hsh_t* hsh_create(size_t klen) +hsh_t* hsh_create() { hsh_t* ht = int_malloc(sizeof(hsh_t)); if(ht) @@ -129,7 +130,6 @@ hsh_t* hsh_create(size_t klen) ht->count = 0; ht->max = INITIAL_MAX; ht->array = alloc_array(ht, ht->max); - ht->klen = klen; if(!ht->array) { int_free(ht); @@ -181,10 +181,12 @@ hsh_index_t* hsh_first(hsh_t* ht) return hsh_next(hi); } -void* hsh_this(hsh_index_t* hi, const void** key) +void* hsh_this(hsh_index_t* hi, const void** key, size_t* klen) { if(key) *key = KEY_DATA(hi->ths); + if(klen) + *klen = hi->ths->klen; return (void*)hi->ths->val; } @@ -229,7 +231,7 @@ static int expand_array(hsh_t* ht) * that hash entries can be removed. */ -static hsh_entry_t** find_entry(hsh_t* ht, const void* key, const void* val) +static hsh_entry_t** find_entry(hsh_t* ht, const void* key, size_t klen, const void* val) { hsh_entry_t** hep; hsh_entry_t* he; @@ -237,8 +239,6 @@ static hsh_entry_t** find_entry(hsh_t* ht, const void* key, const void* val) unsigned int hash; size_t i; - size_t klen = ht->klen; - /* * This is the popular `times 33' hash algorithm which is used by * perl and also appears in Berkeley DB. This is one of the best @@ -278,6 +278,14 @@ static hsh_entry_t** find_entry(hsh_t* ht, const void* key, const void* val) */ hash = 0; + if(klen == HSH_KEY_STRING) + { + for(p = key; *p; p++) + hash = hash * 33 + *p; + + klen = p - (const unsigned char *)key; + } + else { for(p = key, i = klen; i; i--, p++) hash = hash * 33 + *p; @@ -288,6 +296,7 @@ static hsh_entry_t** find_entry(hsh_t* ht, const void* key, const void* val) he; hep = &he->next, he = *hep) { if(he->hash == hash && + he->klen == klen && memcmp(KEY_DATA(he), key, klen) == 0) break; } @@ -296,15 +305,17 @@ static hsh_entry_t** find_entry(hsh_t* ht, const void* key, const void* val) return hep; /* add a new entry for non-NULL val */ - he = int_malloc(sizeof(*he) + klen); + he = int_malloc(sizeof(*he)); + if(he) { - /* Key data points past end of entry */ - memcpy(KEY_DATA(he), key, klen); + /* Key points to external data */ + he->key = key; + he->klen = klen; he->next = NULL; he->hash = hash; - he->val = val; + he->val = val; *hep = he; ht->count++; @@ -313,18 +324,19 @@ static hsh_entry_t** find_entry(hsh_t* ht, const void* key, const void* val) return hep; } -void* hsh_get(hsh_t* ht, const void *key) +void* hsh_get(hsh_t* ht, const void *key, size_t klen) { - hsh_entry_t** he = find_entry(ht, key, NULL); + hsh_entry_t** he = find_entry(ht, key, klen, NULL); + if(he && *he) return (void*)((*he)->val); else return NULL; } -int hsh_set(hsh_t* ht, const void* key, void* val) +int hsh_set(hsh_t* ht, const void* key, size_t klen, void* val) { - hsh_entry_t** hep = find_entry(ht, key, val); + hsh_entry_t** hep = find_entry(ht, key, klen, val); if(hep && *hep) { @@ -344,9 +356,9 @@ int hsh_set(hsh_t* ht, const void* key, void* val) return 0; } -void* hsh_rem(hsh_t* ht, const void* key) +void* hsh_rem(hsh_t* ht, const void* key, size_t klen) { - hsh_entry_t** hep = find_entry(ht, key, NULL); + hsh_entry_t** hep = find_entry(ht, key, klen, NULL); void* val = NULL; if(hep && *hep) @@ -365,3 +377,4 @@ unsigned int hsh_count(hsh_t* ht) { return ht->count; } + diff --git a/src/common/hash.h b/src/common/hash.h index 7e2cb66..df34a7a 100644 --- a/src/common/hash.h +++ b/src/common/hash.h @@ -54,6 +54,14 @@ #ifndef __HSH_H__ #define __HSH_H__ +/* + * OPTIONAL FEATURES + * + * Features to define. You need to build both this file and + * the corresponding hash.c file with whatever options you set here. + * These affect the method signatures, so see the sections below + * for the actual options + */ /* * ARGUMENT DOCUMENTATION @@ -63,6 +71,7 @@ * klen: The length of the key * val: Pointer to the value * hi: A hashtable iterator + * stamp: A unix timestamp */ @@ -76,16 +85,15 @@ typedef struct hsh_t hsh_t; /* Abstract type for scanning hash tables. */ typedef struct hsh_index_t hsh_index_t; - -/* ---------------------------------------------------------------------------------- - * FUNCS +/* ----------------------------------------------------------------------------- + * MAIN */ /* * hsh_create : Create a hash table * - returns an allocated hashtable */ -hsh_t* hsh_create(size_t klen); +hsh_t* hsh_create(); /* * hsh_free : Free a hash table @@ -102,19 +110,19 @@ unsigned int hsh_count(hsh_t* ht); * hsh_get: Retrieves a value from the hash table * - returns the value of the entry */ -void* hsh_get(hsh_t* ht, const void* key); +void* hsh_get(hsh_t* ht, const void* key, size_t klen); /* * hsh_set: Set a value in the hash table * - returns 1 if the entry was added properly */ -int hsh_set(hsh_t* ht, const void* key, void* val); +int hsh_set(hsh_t* ht, const void* key, size_t klen, void* val); /* * hsh_rem: Remove a value from the hash table * - returns the value of the removed entry */ -void* hsh_rem(hsh_t* ht, const void* key); +void* hsh_rem(hsh_t* ht, const void* key, size_t klen); /* * hsh_first: Start enumerating through the hash table @@ -132,6 +140,12 @@ hsh_index_t* hsh_next(hsh_index_t* hi); * hsh_this: While enumerating get current value * - returns the value that the iterator currently points to */ -void* hsh_this(hsh_index_t* hi, const void** key); +void* hsh_this(hsh_index_t* hi, const void** key, size_t* klen); + +/* + * This can be passed as 'klen' in any of the above functions to indicate + * a string-valued key, and have hash compute the length automatically. + */ +#define HSH_KEY_STRING (-1) #endif /* __HSH_H__ */ -- cgit v1.2.3