Tinyhash
This is a library containing multiple C implementations of hashmap.
Loading...
Searching...
No Matches
table.c
Go to the documentation of this file.
1#include "../common/table.h"
2
3#include <stdint.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7
8#include "table.h"
9
10static bool th_sc_table_put_with_key(th_sc_table_t *table, th_key_t *key,
11 th_any_t value);
12
14 table->capacity = 0;
15 table->count = 0;
16 table->entries = NULL;
17}
18
25 th_sc_table_t *table = malloc(sizeof(th_sc_table_t));
26
27 if (table == NULL) {
28 return NULL;
29 }
30
31 th_sc_table_init(table);
32
33 return table;
34}
35
39
50 bool success;
51
52 for (int i = 0; i < src->capacity; i++) {
53 th_sc_entry_t *entry = src->entries[i];
54
55 while (entry != NULL) {
56 success = th_sc_table_put_with_key(dest, &entry->key, entry->value);
57
58 if (success == false) {
59 return false;
60 }
61
62 entry = entry->next;
63 }
64 }
65
66 return true;
67}
68
77 th_sc_table_t new_table;
78 bool success;
79
80 th_sc_table_init(&new_table);
81
82 new_table.capacity = TH_TABLE_NEXT_CAPACITY(table->capacity);
83
84 size_t size = sizeof(th_sc_entry_t *) * new_table.capacity;
85 new_table.entries = malloc(size);
86
87 if (new_table.entries == NULL) {
88 return false;
89 }
90
91 memset(new_table.entries, 0, size);
92
93 success = th_sc_table_copy(&new_table, table);
94 if (success == false) {
95 return false;
96 }
97
99
100 *table = new_table;
101
102 return true;
103}
104
114 // Avoid division by 0
115 if (table->capacity == 0) {
116 return NULL;
117 }
118
119 int index = key->hash % table->capacity;
120 th_sc_entry_t *entry = table->entries[index];
121
122 while (entry != NULL) {
123 if (th_key_is_equal(key, &entry->key)) {
124 return entry;
125 }
126
127 entry = entry->next;
128 }
129
130 return NULL;
131}
132
134 size_t data_size) {
135 th_sc_table_t *table = (th_sc_table_t *)generic_table;
136 th_key_t key = th_key_create(data, data_size);
137
138 th_sc_entry_t *entry = th_sc_table_find(table, &key);
139 if (entry == NULL) {
140 return NULL;
141 }
142
143 return entry->value;
144}
145
156 th_any_t value) {
157 if (table->count >= table->capacity) {
158 if (th_sc_table_increase(table) == false) {
159 return false;
160 }
161 }
162
163 th_sc_entry_t *entry = th_sc_table_find(table, key);
164
165 if (entry == NULL) {
166 int index = key->hash % table->capacity;
167 th_sc_entry_t **bucket = &table->entries[index];
168
169 if (*bucket == NULL) {
170 table->count++;
171 }
172
173 if (th_sc_entry_add(bucket, key, value) == false) {
174 return false;
175 }
176 } else {
177 entry->value = value;
178 }
179
180 return true;
181}
182
184 size_t data_size, th_any_t value) {
185 th_sc_table_t *table = (th_sc_table_t *)generic_table;
186 th_key_t key = th_key_create(data, data_size);
187
188 return th_sc_table_put_with_key(table, &key, value);
189}
190
192 size_t data_size) {
193 th_sc_table_t *table = (th_sc_table_t *)generic_table;
194 th_key_t key = th_key_create(data, data_size);
195
196 th_sc_entry_t *entry = th_sc_table_find(table, &key);
197 if (entry == NULL) {
198 return false;
199 }
200
201 int index = entry->key.hash % table->capacity;
202 th_sc_entry_t **bucket = &table->entries[index];
203
204 if (entry->next == NULL && entry->previous == NULL) {
205 *bucket = NULL;
206 table->count--;
207 } else if (entry->previous == NULL) {
208 *bucket = entry->next;
209 (*bucket)->previous = NULL;
210 } else if (entry->next == NULL) {
211 entry->previous->next = entry->next;
212 } else {
213 entry->previous->next = entry->next;
214 entry->next->previous = entry->previous;
215 }
216
217 free(entry);
218
219 return true;
220}
221
223 th_sc_table_t *table = (th_sc_table_t *)generic_table;
224 th_sc_entry_t *entry;
225 th_sc_entry_t *previous;
226
227 for (int i = 0; i < table->capacity; i++) {
228 entry = table->entries[i];
229
230 while (entry != NULL) {
231 previous = entry;
232 entry = entry->next;
233
234 free(previous);
235 }
236 }
237
238 if (table->entries != NULL) {
239 free(table->entries);
240 }
241
242 th_sc_table_init(table);
243}
244
246 it->current = entry;
247 it->key = &entry->key;
248 it->value = entry->value;
249}
250
259 th_iterator_t *it = *ptr;
261 th_sc_entry_t *current = (th_sc_entry_t *)it->current;
262
263 if (current != NULL && current->next != NULL) {
264 th_sc_iterator_copy_entry(it, current->next);
265 return true;
266 }
267
268 it->index++;
269
270 th_sc_entry_t *entry;
271 for (; it->index < table->capacity; it->index++) {
272 entry = table->entries[it->index];
273
274 if (entry == NULL) {
275 continue;
276 }
277
278 th_sc_iterator_copy_entry(it, entry);
279 return true;
280 }
281
282 *ptr = NULL;
283
284 return false;
285}
286
288 bool is_begin) {
290
291 if (it == NULL) {
292 return NULL;
293 }
294
295 it->index--;
296
297 if (is_begin == true) {
299 }
300
301 return it;
302}
303
305 return (((th_sc_table_t *)generic_table)->count);
306}
#define TH_TABLE_NEXT_CAPACITY(capacity)
Generate the next capacity value absed on a previous one.
Definition table.h:8
bool th_sc_entry_add(th_sc_entry_t **root, th_key_t *key, th_any_t value)
Add an a separate chaining entry to the beginning of a linked list. Return true on success.
Definition entry.c:25
th_iterator_t * th_iterator_create(th_generic_table_t generic_table, th_iterator_next_func_t next)
Allocate then init a new iterator.
Definition iterator.c:16
th_key_t th_key_create(th_any_t data, size_t size)
Create a key struct from data and size, it will automatically compute its hash.
Definition key.c:6
bool th_key_is_equal(th_key_t *first, th_key_t *second)
Key comparator function.
Definition key.c:14
th_iterator_t * th_sc_iterator_begin(th_generic_table_t generic_table, bool is_begin)
Return a new iterator.
Definition table.c:287
void th_sc_table_free(th_generic_table_t generic_table)
Free an separate chaining table.
Definition table.c:222
static bool th_sc_iterator_next(th_iterator_t **ptr)
Get the next key value pair if it exists.
Definition table.c:258
int th_sc_table_len(th_generic_table_t generic_table)
Returns the table length.
Definition table.c:304
static void th_sc_iterator_copy_entry(th_iterator_t *it, th_sc_entry_t *entry)
Definition table.c:245
th_any_t th_sc_table_get(th_generic_table_t generic_table, th_any_t data, size_t data_size)
Get a value from an separate chaining table. Return NULL if it does exist.
Definition table.c:133
static th_sc_entry_t * th_sc_table_find(th_sc_table_t *table, th_key_t *key)
Returns a bucket (entry) depending on a key. Return NULL if the entry does not exist.
Definition table.c:113
bool th_sc_table_put(th_generic_table_t generic_table, th_any_t data, size_t data_size, th_any_t value)
Insert a value within an separate chaining table. Return true on success.
Definition table.c:183
static bool th_sc_table_copy(th_sc_table_t *dest, th_sc_table_t *src)
Copy and rehash every value from a table to another. Return true on success.
Definition table.c:49
static th_sc_table_t * _th_sc_table_create()
Allocate then return a new table.
Definition table.c:24
void th_sc_table_init(th_sc_table_t *table)
Initialize a separate chaining table.
Definition table.c:13
th_generic_table_t th_sc_table_create()
Return an allocated separate chaining table.
Definition table.c:36
static bool th_sc_table_put_with_key(th_sc_table_t *table, th_key_t *key, th_any_t value)
Insert a value within the table with an already existing key.
Definition table.c:155
bool th_sc_table_delete(th_generic_table_t generic_table, th_any_t data, size_t data_size)
Delete a key value pair in an separate chaining table. Return true on success.
Definition table.c:191
static bool th_sc_table_increase(th_sc_table_t *table)
Increase the size of a table.
Definition table.c:76
Represents an iterator that allow to iterate over a generic table.
Definition iterator.h:11
th_any_t current
Definition iterator.h:13
th_any_t value
Definition iterator.h:15
th_generic_table_t generic_table
Definition iterator.h:16
th_key_t * key
Definition iterator.h:14
Represent an entry key.
Definition key.h:14
uint32_t hash
Definition key.h:15
Represents a separate chaining entry.
Definition entry.h:15
struct th_sc_entry_s * previous
Definition entry.h:18
th_any_t value
Definition entry.h:17
th_key_t key
Definition entry.h:16
struct th_sc_entry_s * next
Definition entry.h:19
Represent a separate chaining table.
Definition table.h:16
uint32_t capacity
Definition table.h:18
th_sc_entry_t ** entries
Definition table.h:19
uint32_t count
Definition table.h:17
void * th_generic_table_t
Represents any table.
Definition types.h:14
void * th_any_t
Represent any type of data.
Definition types.h:8