summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authorpdw <>2002-03-24 16:22:26 +0000
committerpdw <>2002-03-24 16:22:26 +0000
commit3004ea063cbb186a63af99a2e13d7cb09f23360d (patch)
treed617af0ad0619334f899d3405350edb9b1b2407b /hash.c
downloadiftop-3004ea063cbb186a63af99a2e13d7cb09f23360d.zip
iftop
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/hash.c b/hash.c
new file mode 100644
index 0000000..6f2a77d
--- /dev/null
+++ b/hash.c
@@ -0,0 +1,112 @@
+/* hash table */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "hash.h"
+
+hash_status_enum hash_insert(hash_type* hash_table, void* key, void* rec) {
+ hash_node_type *p, *p0;
+ int bucket;
+
+ /************************************************
+ * allocate node for data and insert in table *
+ ************************************************/
+
+
+ /* insert node at beginning of list */
+ bucket = hash_table->hash(key);
+ if ((p = malloc(sizeof(hash_node_type))) == 0)
+ return HASH_STATUS_MEM_EXHAUSTED;
+ p0 = hash_table->table[bucket];
+ hash_table->table[bucket] = p;
+ p->next = p0;
+ p->key = hash_table->copy_key(key);
+ p->rec = rec;
+ return HASH_STATUS_OK;
+}
+
+hash_status_enum hash_delete(hash_type* hash_table, void* key) {
+ hash_node_type *p0, *p;
+ int bucket;
+
+ /********************************************
+ * delete node containing data from table *
+ ********************************************/
+
+ /* find node */
+ p0 = 0;
+ bucket = hash_table->hash(key);
+ p = hash_table->table[bucket];
+ while (p && !hash_table->compare(p->key, key)) {
+ p0 = p;
+ p = p->next;
+ }
+ if (!p) return HASH_STATUS_KEY_NOT_FOUND;
+
+ /* p designates node to delete, remove it from list */
+ if (p0)
+ /* not first node, p0 points to previous node */
+ p0->next = p->next;
+ else
+ /* first node on chain */
+ hash_table->table[bucket] = p->next;
+
+ hash_table->delete_key(p->key);
+ free (p);
+ return HASH_STATUS_OK;
+}
+
+hash_status_enum hash_find(hash_type* hash_table, void* key, void **rec) {
+ hash_node_type *p;
+
+ /*******************************
+ * find node containing data *
+ *******************************/
+ p = hash_table->table[hash_table->hash(key)];
+ while (p && !hash_table->compare(p->key, key))
+ p = p->next;
+ if (!p) return HASH_STATUS_KEY_NOT_FOUND;
+ *rec = p->rec;
+ return HASH_STATUS_OK;
+}
+
+hash_status_enum hash_next_item(hash_type* hash_table, hash_node_type** ppnode) {
+ int i;
+ if(*ppnode != NULL) {
+ if((*ppnode)->next != NULL) {
+ *ppnode = (*ppnode)->next;
+ return HASH_STATUS_OK;
+ }
+ i = hash_table->hash((*ppnode)->key) + 1;
+ }
+ else {
+ /* first node */
+ i = 0;
+ }
+ while(i < hash_table->size && hash_table->table[i] == NULL) {
+ i++;
+ }
+ if(i == hash_table->size) {
+ *ppnode = NULL;
+ return HASH_STATUS_KEY_NOT_FOUND;
+ }
+ *ppnode = hash_table->table[i];
+ return HASH_STATUS_OK;
+}
+
+/*
+ * Allocate and return a hash
+ */
+hash_status_enum hash_initialise(hash_type* hash_table) {
+ if ((hash_table->table = calloc(hash_table->size, sizeof(hash_node_type *))) == 0) {
+ fprintf (stderr, "out of memory (hash_table)\n");
+ return HASH_STATUS_MEM_EXHAUSTED;
+ }
+ return HASH_STATUS_OK;
+}
+
+hash_status_enum hash_destroy(hash_type* hash_table) {
+ free(hash_table->table);
+ return HASH_STATUS_OK;
+}
+