aboutsummaryrefslogtreecommitdiff
path: root/htable.c
blob: a39c3c65dff14de1cc43f61c8508552f5dea5e9d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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;
}