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 "entry.h"
9#include "table.h"
10
11static bool th_oa_table_put_with_key(th_oa_table_t *table, th_key_t *key,
12 th_any_t value);
13
15 table->capacity = 0;
16 table->count = 0;
17 table->entries = NULL;
18}
19
27 th_oa_table_t *table = malloc(sizeof(th_oa_table_t));
28
29 if (table == NULL) {
30 return NULL;
31 }
32
33 th_oa_table_init(table);
34
35 return table;
36}
37
41
52 bool success;
53
54 for (int i = 0; i < src->capacity; i++) {
55 th_oa_entry_t *entry = &src->entries[i];
56
57 if (entry->key == NULL) {
58 continue;
59 }
60
61 success = th_oa_table_put_with_key(dest, entry->key, entry->value);
62
63 if (success == false) {
64 return false;
65 }
66 }
67
68 return true;
69}
70
79 th_oa_table_t new_table;
80 bool success;
81
82 th_oa_table_init(&new_table);
83
84 new_table.capacity = TH_TABLE_NEXT_CAPACITY(table->capacity);
85
86 size_t size = sizeof(th_oa_entry_t) * new_table.capacity;
87
88 new_table.entries = malloc(size);
89 if (new_table.entries == NULL) {
90 return false;
91 }
92
93 memset(new_table.entries, 0, size);
94
95 success = th_oa_table_copy(&new_table, table);
96 if (success == false) {
97 return false;
98 }
99
100 th_oa_table_free(table);
101
102 *table = new_table;
103
104 return true;
105}
106
116 int index = key->hash % table->capacity;
117
118 th_oa_entry_t *tombstone = NULL;
119 for (;;) {
120 th_oa_entry_t *entry = &table->entries[index];
121
122 if (entry->key == NULL) {
123 if (entry->is_tombstone == false) {
124 return tombstone != NULL ? tombstone : entry;
125 } else {
126 if (tombstone == NULL) {
127 tombstone = entry;
128 }
129 }
130 } else if (th_key_is_equal(key, entry->key) == true) {
131 return entry;
132 }
133
134 index = (index + 1) % table->capacity;
135 }
136}
137
139 size_t data_size) {
140 th_oa_table_t *table = (th_oa_table_t *)generic_table;
141 if (table->capacity == 0) {
142 return NULL;
143 }
144
145 th_key_t key = th_key_create(data, data_size);
146 th_oa_entry_t *entry = th_oa_table_find(table, &key);
147 if (entry->key == NULL) {
148 return NULL;
149 }
150
151 return entry->value;
152}
153
164 th_any_t value) {
165 if (table->count >= table->capacity * TH_OA_LOAD_FACTOR) {
166 if (th_oa_table_increase(table) == false) {
167 return false;
168 }
169 }
170
171 th_oa_entry_t *entry = th_oa_table_find(table, key);
172
173 if (entry->key == NULL) {
174 if (entry->is_tombstone == false) {
175 table->count++;
176 }
177 } else {
178 free(entry->key);
179 }
180
181 entry->key = malloc(sizeof(th_key_t));
182 *entry->key = *key;
183 entry->value = value;
184 entry->is_tombstone = false;
185
186 return true;
187}
188
190 size_t data_size, th_any_t value) {
191 th_oa_table_t *table = (th_oa_table_t *)generic_table;
192 th_key_t key = th_key_create(data, data_size);
193
194 return th_oa_table_put_with_key(table, &key, value);
195}
196
198 size_t data_size) {
199 th_oa_table_t *table = (th_oa_table_t *)generic_table;
200 if (table->capacity == 0) {
201 return false;
202 }
203
204 th_key_t key = th_key_create(data, data_size);
205
206 th_oa_entry_t *entry = th_oa_table_find(table, &key);
207 if (entry->key == NULL) {
208 return false;
209 }
210
211 free(entry->key);
212
213 entry->key = NULL;
214 entry->is_tombstone = true;
215
216 return true;
217}
218
220 th_oa_table_t *table = (th_oa_table_t *)generic_table;
221
222 for (int i = 0; i < table->capacity; i++) {
223 th_oa_entry_t *entry = &table->entries[i];
224
225 if (entry->key == NULL) {
226 continue;
227 }
228
229 free(entry->key);
230 }
231
232 if (table->entries != NULL) {
233 free(table->entries);
234 }
235
236 th_oa_table_init(table);
237}
238
247 th_iterator_t *it = *ptr;
249
250 it->index++;
251
252 th_oa_entry_t *entry;
253 for (; it->index < table->capacity; it->index++) {
254 entry = &table->entries[it->index];
255
256 if (entry->key == NULL) {
257 continue;
258 }
259
260 it->current = entry;
261 it->key = entry->key;
262 it->value = entry->value;
263
264 return true;
265 }
266
267 *ptr = NULL;
268
269 return false;
270}
271
273 bool is_begin) {
275
276 if (it == NULL) {
277 return NULL;
278 }
279
280 it->index--;
281
282 if (is_begin == true) {
284 }
285
286 return it;
287}
288
290 return (((th_oa_table_t *)generic_table)->count);
291}
#define TH_TABLE_NEXT_CAPACITY(capacity)
Generate the next capacity value absed on a previous one.
Definition table.h:8
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
struct th_oa_entry_s th_oa_entry_t
Represent an entry within a bucket.
static bool th_oa_table_copy(th_oa_table_t *dest, th_oa_table_t *src)
Copy and rehash every value from a table to another. Return true on success.
Definition table.c:51
static bool th_oa_iterator_next(th_iterator_t **ptr)
Get the next key value pair if it exists.
Definition table.c:246
static bool th_oa_table_increase(th_oa_table_t *table)
Increase the size of a table.
Definition table.c:78
bool th_oa_table_delete(th_generic_table_t generic_table, th_any_t data, size_t data_size)
Delete a key value pair in an open addressing table. Return true on success.
Definition table.c:197
bool th_oa_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 open addressing table. Return true on success.
Definition table.c:189
void th_oa_table_init(th_oa_table_t *table)
Initialize open adressing table values.
Definition table.c:14
th_any_t th_oa_table_get(th_generic_table_t generic_table, th_any_t data, size_t data_size)
Get a value from an open addressing table. Return NULL if it does exist.
Definition table.c:138
void th_oa_table_free(th_generic_table_t generic_table)
Free an open addressing table.
Definition table.c:219
th_iterator_t * th_oa_iterator_begin(th_generic_table_t generic_table, bool is_begin)
Return a new iterator.
Definition table.c:272
static th_oa_table_t * _th_oa_table_create()
Allocate then initialize an open addressing table. It can return NULL.
Definition table.c:26
static th_oa_entry_t * th_oa_table_find(th_oa_table_t *table, th_key_t *key)
Returns a bucket (entry) depending on a key. It can return a tomstone or an empty bucket.
Definition table.c:115
int th_oa_table_len(th_generic_table_t generic_table)
Returns the table length.
Definition table.c:289
static bool th_oa_table_put_with_key(th_oa_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:163
th_generic_table_t th_oa_table_create()
Return an allocated open addressing table struct.
Definition table.c:38
#define TH_OA_LOAD_FACTOR
Load factor.
Definition table.h:16
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
Represent an entry within a bucket.
Definition entry.h:15
th_key_t * key
Definition entry.h:16
bool is_tombstone
Definition entry.h:18
th_any_t value
Definition entry.h:17
uint32_t capacity
Definition table.h:20
th_oa_entry_t * entries
Definition table.h:21
uint32_t count
Definition table.h:19
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