aboutsummaryrefslogtreecommitdiff
path: root/htable.c
diff options
context:
space:
mode:
Diffstat (limited to 'htable.c')
-rw-r--r--htable.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/htable.c b/htable.c
new file mode 100644
index 0000000..a39c3c6
--- /dev/null
+++ b/htable.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "htable.h"
+
+static htable_node_t *__htable_lookup( htable_t *ht, unsigned int id );
+
+void htable_init( htable_t *ht, unsigned int cap ) {
+ unsigned int i;
+
+ ht->ht_hash = (list_t*) malloc( sizeof( list_t ) * cap );
+ ht->ht_cap = cap;
+ ht->ht_size = 0;
+
+ for( i = 0; i < cap; i++ )
+ list_init( &ht->ht_hash[ i ] );
+}
+
+void htable_destroy( htable_t *ht ) {
+ unsigned int i;
+ htable_node_t *hn;
+
+ for( i = 0; i < ht->ht_cap; i++ ) {
+ list_iterate_begin( &ht->ht_hash[ i ], hn, htable_node_t, hn_link ) {
+ free( hn );
+ } list_iterate_end();
+ }
+
+ free( ht->ht_hash );
+}
+
+void *htable_get( htable_t *ht, unsigned int id ) {
+ htable_node_t *hn;
+
+ if( ( hn = __htable_lookup( ht, id ) ) ) return hn->hn_data;
+ else return NULL;
+}
+
+void *htable_put( htable_t *ht, unsigned int id, void *data ) {
+ htable_node_t *hn;
+ void *old = NULL;
+
+ if( !( hn = __htable_lookup( ht, id ) ) ) {
+ hn = (htable_node_t*) malloc( sizeof( htable_node_t ) );
+ hn->hn_id = id;
+ list_insert_head( &ht->ht_hash[ id % ht->ht_cap ], &hn->hn_link );
+ ht->ht_size++;
+ } else old = hn->hn_data;
+
+ hn->hn_data = data;
+
+ return old;
+}
+
+void *htable_remove( htable_t *ht, unsigned int id ) {
+ htable_node_t *hn;
+
+ if( ( hn = __htable_lookup( ht, id ) ) ) {
+ void *data = hn->hn_data;
+ list_remove( &hn->hn_link );
+ free( hn );
+ ht->ht_size--;
+ return data;
+ } else return NULL;
+}
+
+htable_node_t *__htable_lookup( htable_t *ht, unsigned int id ) {
+ htable_node_t *hn;
+
+ list_iterate_begin( &ht->ht_hash[ id % ht->ht_cap ], hn, htable_node_t, hn_link ) {
+ if( hn->hn_id == id ) return hn;
+ } list_iterate_end();
+
+ return NULL;
+} \ No newline at end of file