add hashmap
This commit is contained in:
parent
986006449d
commit
112d98edcd
1 changed files with 244 additions and 146 deletions
114
slibs.h
114
slibs.h
|
@ -117,6 +117,107 @@
|
|||
(name) != sl_vec_end(vec); \
|
||||
++(name)
|
||||
|
||||
// TODO: Linked List
|
||||
|
||||
// #define sl_list(name, type) \
|
||||
// struct name \
|
||||
// { \
|
||||
// type *data; \
|
||||
// struct name *next; \
|
||||
// }
|
||||
|
||||
// #define sl_list_append(list, value) \
|
||||
// { \
|
||||
// sl_auto(curr, list);\
|
||||
|
||||
// } \
|
||||
|
||||
// Hashmap
|
||||
|
||||
#define SL_MAX_HASH_ENTRIES 512
|
||||
int sl_hash(const char *str);
|
||||
|
||||
#define sl_map(name, valuetype) \
|
||||
typedef valuetype sl_##name##_type; \
|
||||
\
|
||||
typedef struct sl_##name##_entry \
|
||||
{ \
|
||||
const char *key; \
|
||||
sl_##name##_type value; \
|
||||
} sl_##name##_entry; \
|
||||
\
|
||||
typedef sl_vec(sl_##name##_entry) sl_##name##_entry_vec; \
|
||||
\
|
||||
typedef struct sl_##name##_map \
|
||||
{ \
|
||||
sl_##name##_entry_vec *entries[SL_MAX_HASH_ENTRIES]; \
|
||||
} sl_##name##_map; \
|
||||
\
|
||||
sl_##name##_map name = {0};
|
||||
|
||||
#define sl_map_set(map, key_, val) \
|
||||
{ \
|
||||
int hash = sl_hash(key_); \
|
||||
sl_##map##_entry_vec *entry = map.entries[hash]; \
|
||||
if (!entry) \
|
||||
{ \
|
||||
entry = calloc(1, sizeof(sl_##map##_entry_vec)); \
|
||||
map.entries[hash] = entry; \
|
||||
} \
|
||||
int found = 0; \
|
||||
for (sl_vec_it(el, *entry)) \
|
||||
{ \
|
||||
if (strcmp(el->key, key_) == 0) \
|
||||
{ \
|
||||
el->value = val; \
|
||||
found = 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if (!found) \
|
||||
{ \
|
||||
sl_##map##_entry new_entry = {key_, val}; \
|
||||
sl_vec_push(*entry, new_entry) \
|
||||
} \
|
||||
}
|
||||
|
||||
#define sl_map_get(map, key_) \
|
||||
({ \
|
||||
sl_##map##_entry_vec *entry = map.entries[sl_hash(key_)]; \
|
||||
sl_##map##_type* value = NULL; \
|
||||
\
|
||||
if (entry) \
|
||||
{ \
|
||||
for (sl_vec_it(el, *entry)) \
|
||||
{ \
|
||||
if (strcmp(el->key, key_) == 0) \
|
||||
{ \
|
||||
value = &el->value; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
value; \
|
||||
})
|
||||
|
||||
#ifdef SL_IMPLEMENTATION
|
||||
int sl_hash(const char *str)
|
||||
{
|
||||
uint32_t seed = 0;
|
||||
size_t len = strlen(str);
|
||||
|
||||
for (size_t i = 0; i < len && i < sizeof(uint32_t); i++)
|
||||
{
|
||||
seed <<= 8;
|
||||
seed |= str[i];
|
||||
}
|
||||
|
||||
srand(seed);
|
||||
return rand() % SL_MAX_HASH_ENTRIES;
|
||||
}
|
||||
#endif
|
||||
|
||||
// String
|
||||
|
||||
typedef sl_vec(char) sl_string;
|
||||
|
@ -174,8 +275,7 @@ void sl_append_c_str(sl_string *sl_str, const char *c_str)
|
|||
|
||||
#define sl_ptr_make(raw_ptr) \
|
||||
{ \
|
||||
raw_ptr, 1 \
|
||||
}
|
||||
raw_ptr, 1}
|
||||
|
||||
#define sl_ptr_release(smart_ptr) \
|
||||
({ \
|
||||
|
@ -209,17 +309,14 @@ void sl_write_file(const char *filename, const sl_string buffer);
|
|||
FILE *sl_open_file(const char *filename, const char *mode)
|
||||
{
|
||||
FILE *file = fopen(filename, mode);
|
||||
if (!file)
|
||||
{
|
||||
fprintf(stderr, "Error: could not open file %s\n", filename);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
sl_string *sl_read_file(const char *filename)
|
||||
{
|
||||
FILE *file = sl_open_file(filename, "r");
|
||||
if(!file) return NULL;
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
size_t file_size = ftell(file);
|
||||
|
@ -239,7 +336,8 @@ sl_string *sl_read_file(const char *filename)
|
|||
void sl_write_file(const char *filename, sl_string buffer)
|
||||
{
|
||||
FILE *file = sl_open_file(filename, "w");
|
||||
if(!file) return;
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
fputs(sl_c_str(buffer), file);
|
||||
fclose(file);
|
||||
|
|
Loading…
Add table
Reference in a new issue