468de8139420139d40a9296895a71171f05a1f78
5 #include "cgds/HashTable.h"
7 void _hashtable_init(HashTable
* hashTable
, size_t dataSize
, size_t hashSize
)
9 hashTable
->hashSize
= hashSize
;
10 hashTable
->dataSize
= dataSize
;
11 hashTable
->head
= safe_malloc(hashSize
* sizeof(HashCell
*));
12 for (UInt i
= 0; i
< hashSize
; i
++)
13 hashTable
->head
[i
] = NULL
;
17 HashTable
* _hashtable_new(size_t dataSize
, size_t hashSize
)
19 HashTable
* hashTable
= (HashTable
*) safe_malloc(sizeof(HashTable
));
20 _hashtable_init(hashTable
, dataSize
, hashSize
);
24 HashTable
* hashtable_copy(HashTable
* hashTable
)
26 HashTable
* hashTableCopy
=
27 _hashtable_new(hashTable
->dataSize
, hashTable
->hashSize
);
28 hashTableCopy
->size
= hashTable
->size
;
29 for (UInt i
= 0; i
< hashTable
->hashSize
; i
++)
31 HashCell
*cell
= hashTable
->head
[i
],
32 *cellCopy
= hashTableCopy
->head
[i
],
36 // cellCopy == NULL (from empty list)
37 cellCopy
= (HashCell
*) safe_malloc(sizeof(HashCell
));
38 cellCopy
->key
= (char*) safe_malloc(strlen(cell
->key
) + 1);
39 strcpy(cellCopy
->key
, cell
->key
);
40 cellCopy
->data
= safe_malloc(hashTable
->dataSize
);
41 memcpy(cellCopy
->data
, cell
->data
, hashTable
->dataSize
);
42 if (prev
== NULL
) hashTableCopy
->head
[i
] = cellCopy
;
43 else prev
->next
= cellCopy
;
47 if (cellCopy
!= NULL
) cellCopy
->next
= NULL
;
52 bool hashtable_empty(HashTable
* hashTable
)
54 return (hashTable
->size
== 0);
57 UInt
hashtable_size(HashTable
* hashTable
)
59 return hashTable
->size
;
62 // Function (string) key --> (integer) hash [internal usage]
63 UInt
_compute_hash(char* key
, size_t hashSize
)
66 for (unsigned char* s
= key
; *s
!= '\0'; s
++)
67 // NOTE: '31' from here https://stackoverflow.com/a/4384446
68 res
= (*s
+ 31 * res
) % hashSize
;
72 void* _hashtable_get(HashTable
* hashTable
, char* key
)
74 UInt hashIdx
= _compute_hash(key
, hashTable
->hashSize
);
75 HashCell
* cell
= hashTable
->head
[hashIdx
];
78 if (strcmp(cell
->key
, key
) == 0)
85 void _hashtable_set(HashTable
* hashTable
, char* key
, void* data
)
87 UInt hashIdx
= _compute_hash(key
, hashTable
->hashSize
);
88 HashCell
*cell
= hashTable
->head
[hashIdx
],
92 if (strcmp(cell
->key
, key
) == 0)
95 memcpy(cell
->data
, data
, hashTable
->dataSize
);
101 // New element: insert after prev (which may be NULL)
102 HashCell
* newCell
= (HashCell
*) safe_malloc(sizeof(HashCell
));
103 newCell
->key
= (char*) safe_malloc(strlen(key
) + 1);
104 strcpy(newCell
->key
, key
);
105 newCell
->data
= safe_malloc(hashTable
->dataSize
);
106 memcpy(newCell
->data
, data
, hashTable
->dataSize
);
107 newCell
->next
= NULL
;
109 hashTable
->head
[hashIdx
] = newCell
;
111 prev
->next
= newCell
;
115 void hashtable_delete(HashTable
* hashTable
, char* key
)
117 UInt hashIdx
= _compute_hash(key
, hashTable
->hashSize
);
118 HashCell
*cell
= hashTable
->head
[hashIdx
],
122 if (strcmp(cell
->key
, key
) == 0)
125 hashTable
->head
[hashIdx
] = cell
->next
;
127 prev
->next
= cell
->next
;
128 safe_free(cell
->key
);
129 safe_free(cell
->data
);
139 void hashtable_clear(HashTable
* hashTable
)
141 for (UInt i
= 0; i
< hashTable
->hashSize
; i
++)
143 HashCell
* cell
= hashTable
->head
[i
];
146 HashCell
* next
= cell
->next
;
147 safe_free(cell
->key
);
148 safe_free(cell
->data
);
152 hashTable
->head
[i
] = NULL
;
157 void hashtable_destroy(HashTable
* hashTable
)
159 hashtable_clear(hashTable
);
160 safe_free(hashTable
->head
);
161 safe_free(hashTable
);