2 * Part of Very Secure FTPd
7 * Routines to handle simple hash table lookups and modifications.
18 struct hash_node
* p_prev
;
19 struct hash_node
* p_next
;
25 unsigned int key_size
;
26 unsigned int value_size
;
28 struct hash_node
** p_nodes
;
31 /* Internal functions */
32 struct hash_node
** hash_get_bucket(struct hash
* p_hash
, void* p_key
);
33 struct hash_node
* hash_get_node_by_key(struct hash
* p_hash
, void* p_key
);
36 hash_alloc(unsigned int buckets
, unsigned int key_size
,
37 unsigned int value_size
, hashfunc_t hash_func
)
40 struct hash
* p_hash
= vsf_sysutil_malloc(sizeof(*p_hash
));
41 p_hash
->buckets
= buckets
;
42 p_hash
->key_size
= key_size
;
43 p_hash
->value_size
= value_size
;
44 p_hash
->hash_func
= hash_func
;
45 size
= sizeof(struct hash_node
*) * buckets
;
46 p_hash
->p_nodes
= vsf_sysutil_malloc(size
);
47 vsf_sysutil_memclr(p_hash
->p_nodes
, size
);
52 hash_lookup_entry(struct hash
* p_hash
, void* p_key
)
54 struct hash_node
* p_node
= hash_get_node_by_key(p_hash
, p_key
);
59 return p_node
->p_value
;
63 hash_add_entry(struct hash
* p_hash
, void* p_key
, void* p_value
)
65 struct hash_node
** p_bucket
;
66 struct hash_node
* p_new_node
;
67 if (hash_lookup_entry(p_hash
, p_key
))
69 bug("duplicate hash key");
71 p_bucket
= hash_get_bucket(p_hash
, p_key
);
72 p_new_node
= vsf_sysutil_malloc(sizeof(*p_new_node
));
73 p_new_node
->p_prev
= 0;
74 p_new_node
->p_next
= 0;
75 p_new_node
->p_key
= vsf_sysutil_malloc(p_hash
->key_size
);
76 vsf_sysutil_memcpy(p_new_node
->p_key
, p_key
, p_hash
->key_size
);
77 p_new_node
->p_value
= vsf_sysutil_malloc(p_hash
->value_size
);
78 vsf_sysutil_memcpy(p_new_node
->p_value
, p_value
, p_hash
->value_size
);
82 *p_bucket
= p_new_node
;
86 p_new_node
->p_next
= *p_bucket
;
87 (*p_bucket
)->p_prev
= p_new_node
;
88 *p_bucket
= p_new_node
;
93 hash_free_entry(struct hash
* p_hash
, void* p_key
)
95 struct hash_node
* p_node
= hash_get_node_by_key(p_hash
, p_key
);
98 bug("hash node not found");
100 vsf_sysutil_free(p_node
->p_key
);
101 vsf_sysutil_free(p_node
->p_value
);
105 p_node
->p_prev
->p_next
= p_node
->p_next
;
109 struct hash_node
** p_bucket
= hash_get_bucket(p_hash
, p_key
);
110 *p_bucket
= p_node
->p_next
;
114 p_node
->p_next
->p_prev
= p_node
->p_prev
;
117 vsf_sysutil_free(p_node
);
121 hash_get_bucket(struct hash
* p_hash
, void* p_key
)
123 unsigned int bucket
= (*p_hash
->hash_func
)(p_hash
->buckets
, p_key
);
124 if (bucket
>= p_hash
->buckets
)
126 bug("bad bucket lookup");
128 return &(p_hash
->p_nodes
[bucket
]);
132 hash_get_node_by_key(struct hash
* p_hash
, void* p_key
)
134 struct hash_node
** p_bucket
= hash_get_bucket(p_hash
, p_key
);
135 struct hash_node
* p_node
= *p_bucket
;
140 while (p_node
!= 0 &&
141 vsf_sysutil_memcmp(p_key
, p_node
->p_key
, p_hash
->key_size
) != 0)
143 p_node
= p_node
->p_next
;