summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2006-01-25 04:07:04 +0000
committerStef Walter <stef@memberwebs.com>2006-01-25 04:07:04 +0000
commit7fcead4473bc224bc8c6a66e2db3b3ee87f751d4 (patch)
treed92c54aed884ed001f7901bbb4bef9623975df76 /src/common
parent26a677b17880a14b9345270cb15b37d27d7d4797 (diff)
Configuration file parsing for rrdbotd.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/hash.c53
-rw-r--r--src/common/hash.h30
2 files changed, 55 insertions, 28 deletions
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 <stdlib.h>
#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__ */