@@ -231,27 +231,25 @@ int round_up_pow2(int v)
231231 *
232232 * Return: The pointer of created hashmap.
233233 */
234- hashmap_t * hashmap_create (int size )
234+ hashmap_t * hashmap_create (int cap )
235235{
236236 hashmap_t * map = malloc (sizeof (hashmap_t ));
237237
238238 if (!map ) {
239- printf ("Failed to allocate hashmap_t with size %d\n" , size );
239+ printf ("Failed to allocate hashmap_t with capacity %d\n" , cap );
240240 return NULL ;
241241 }
242242
243- map -> size = round_up_pow2 (size );
244- map -> buckets = malloc (map -> size * sizeof (hashmap_node_t * ));
243+ map -> size = 0 ;
244+ map -> cap = round_up_pow2 (cap );
245+ map -> buckets = calloc (map -> cap , sizeof (hashmap_node_t * ));
245246
246247 if (!map -> buckets ) {
247248 printf ("Failed to allocate buckets in hashmap_t\n" );
248249 free (map );
249250 return NULL ;
250251 }
251252
252- for (int i = 0 ; i < map -> size ; i ++ )
253- map -> buckets [i ] = 0 ;
254-
255253 return map ;
256254}
257255
@@ -290,6 +288,47 @@ hashmap_node_t *hashmap_node_new(char *key, void *val)
290288 return node ;
291289}
292290
291+ void hashmap_rehash (hashmap_t * map )
292+ {
293+ if (!map )
294+ return ;
295+
296+ int old_cap = map -> cap ;
297+ hashmap_node_t * * old_buckets = map -> buckets ;
298+
299+ map -> cap *= 2 ;
300+ map -> buckets = calloc (map -> cap , sizeof (hashmap_node_t * ));
301+
302+ if (!map -> buckets ) {
303+ printf ("Failed to allocate new buckets in hashmap_t\n" );
304+ map -> buckets = old_buckets ;
305+ map -> cap = old_cap ;
306+ return ;
307+ }
308+
309+ for (int i = 0 ; i < old_cap ; i ++ ) {
310+ hashmap_node_t * cur = old_buckets [i ], * next , * target_cur ;
311+
312+ while (cur ) {
313+ next = cur -> next ;
314+ cur -> next = NULL ;
315+ int index = hashmap_hash_index (map -> cap , cur -> key );
316+ target_cur = map -> buckets [index ];
317+
318+ if (!target_cur ) {
319+ map -> buckets [index ] = cur ;
320+ } else {
321+ cur -> next = target_cur ;
322+ map -> buckets [index ] = cur ;
323+ }
324+
325+ cur = next ;
326+ }
327+ }
328+
329+ free (old_buckets );
330+ }
331+
293332/**
294333 * hashmap_put() - puts a key-value pair into given hashmap.
295334 * If key already contains a value, then replace it with new
@@ -304,42 +343,59 @@ void hashmap_put(hashmap_t *map, char *key, void *val)
304343 if (!map )
305344 return ;
306345
307- int index = hashmap_hash_index (map -> size , key );
308- hashmap_node_t * cur = map -> buckets [index ];
346+ int index = hashmap_hash_index (map -> cap , key );
347+ hashmap_node_t * cur = map -> buckets [index ],
348+ * new_node = hashmap_node_new (key , val );
309349
310350 if (!cur ) {
311- map -> buckets [index ] = hashmap_node_new ( key , val ) ;
351+ map -> buckets [index ] = new_node ;
312352 } else {
313353 while (cur -> next )
314354 cur = cur -> next ;
315- cur -> next = hashmap_node_new ( key , val ) ;
355+ cur -> next = new_node ;
316356 }
317357
318- /* TODO: Rehash if size exceeds size * load factor */
358+ map -> size ++ ;
359+ if ((map -> cap >> 2 ) * 3 <= map -> size )
360+ hashmap_rehash (map );
319361}
320362
321363/**
322- * hashmap_get () - gets value from hashmap from given key.
364+ * hashmap_get_node () - gets key- value pair node from hashmap from given key.
323365 * @map: The hashmap to be looked up. Must no be NULL.
324366 * @key: The key string. May be NULL.
325367 *
326368 * Return: The look up result, if the key-value pair entry
327- * exists, then returns its value's address , NULL otherwise.
369+ * exists, then returns address of itself , NULL otherwise.
328370 */
329- void * hashmap_get (hashmap_t * map , char * key )
371+ hashmap_node_t * hashmap_get_node (hashmap_t * map , char * key )
330372{
331373 if (!map )
332374 return NULL ;
333375
334- int index = hashmap_hash_index (map -> size , key );
376+ int index = hashmap_hash_index (map -> cap , key );
335377
336378 for (hashmap_node_t * cur = map -> buckets [index ]; cur ; cur = cur -> next )
337379 if (!strcmp (cur -> key , key ))
338- return cur -> val ;
380+ return cur ;
339381
340382 return NULL ;
341383}
342384
385+ /**
386+ * hashmap_get() - gets value from hashmap from given key.
387+ * @map: The hashmap to be looked up. Must no be NULL.
388+ * @key: The key string. May be NULL.
389+ *
390+ * Return: The look up result, if the key-value pair entry
391+ * exists, then returns its value's address, NULL otherwise.
392+ */
393+ void * hashmap_get (hashmap_t * map , char * key )
394+ {
395+ hashmap_node_t * node = hashmap_get_node (map , key );
396+ return node ? node -> val : NULL ;
397+ }
398+
343399/**
344400 * hashmap_contains() - checks if the key-value pair entry exists
345401 * from given key.
@@ -351,7 +407,7 @@ void *hashmap_get(hashmap_t *map, char *key)
351407 */
352408bool hashmap_contains (hashmap_t * map , char * key )
353409{
354- return hashmap_get (map , key );
410+ return hashmap_get_node (map , key );
355411}
356412
357413/**
0 commit comments