Added hashmap source files
This commit is contained in:
parent
ac80889190
commit
da7d31bad8
|
@ -0,0 +1,164 @@
|
|||
// SPDX-License-Identifier: BSD-2
|
||||
|
||||
#include <hashmap.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAP_INIT_SIZE 1024
|
||||
|
||||
struct hashmap_elem {
|
||||
int key;
|
||||
int in_use;
|
||||
void *val;
|
||||
};
|
||||
|
||||
struct hashmap_map {
|
||||
int max_size;
|
||||
int curr_size;
|
||||
struct hashmap_elem *data;
|
||||
};
|
||||
|
||||
map_t hashmap_new(void)
|
||||
{
|
||||
struct hashmap_map *m;
|
||||
|
||||
m = calloc(1, sizeof(struct hashmap_map));
|
||||
if (!m)
|
||||
goto err;
|
||||
|
||||
m->data = calloc(MAP_INIT_SIZE, sizeof(struct hashmap_elem));
|
||||
if (!m->data)
|
||||
goto err;
|
||||
|
||||
m->max_size = MAP_INIT_SIZE;
|
||||
m->curr_size = 0;
|
||||
|
||||
return m;
|
||||
|
||||
err:
|
||||
hashmap_free(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int _hashmap_hash_int(struct hashmap_map *m, unsigned int key)
|
||||
{
|
||||
key += (key << 12);
|
||||
key ^= (key >> 22);
|
||||
key += (key << 4);
|
||||
key ^= (key >> 9);
|
||||
key += (key << 10);
|
||||
key ^= (key >> 2);
|
||||
key += (key << 7);
|
||||
key ^= (key >> 12);
|
||||
|
||||
key = (key >> 3) * 2654435761;
|
||||
|
||||
return key % m->max_size;
|
||||
}
|
||||
|
||||
int _hashmap_hash(struct hashmap_map *m, int key)
|
||||
{
|
||||
int pos;
|
||||
int i;
|
||||
|
||||
if (m->curr_size == m->max_size)
|
||||
return MAP_FULL;
|
||||
|
||||
pos = _hashmap_hash_int(m, key);
|
||||
i = 0;
|
||||
|
||||
while (i < m->max_size) {
|
||||
if (!m->data[pos].in_use)
|
||||
return pos;
|
||||
|
||||
if (m->data[pos].key == key && m->data[pos].in_use)
|
||||
return pos;
|
||||
|
||||
pos = (pos + 1) % m->max_size;
|
||||
i++;
|
||||
}
|
||||
|
||||
return MAP_FULL;
|
||||
}
|
||||
|
||||
int _hashmap_rehash(struct hashmap_map *m)
|
||||
{
|
||||
int i;
|
||||
int old_size;
|
||||
int status;
|
||||
struct hashmap_elem *curr;
|
||||
struct hashmap_elem *temp;
|
||||
|
||||
temp = calloc(2 * m->max_size, sizeof(struct hashmap_elem));
|
||||
if (!temp)
|
||||
return MAP_OMEM;
|
||||
|
||||
curr = m->data;
|
||||
m->data = temp;
|
||||
|
||||
old_size = m->max_size;
|
||||
m->max_size *= 2;
|
||||
m->curr_size = 0;
|
||||
|
||||
for (i = 0; i < old_size; i++) {
|
||||
status = hashmap_put(m, curr[i].key, curr[i].val);
|
||||
if (status != MAP_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
free(curr);
|
||||
|
||||
return MAP_OK;
|
||||
}
|
||||
|
||||
int hashmap_put(map_t map, int key, void *value)
|
||||
{
|
||||
int index;
|
||||
struct hashmap_map *m;
|
||||
|
||||
m = (struct hashmap_map *) map;
|
||||
index = _hashmap_hash(m, key);
|
||||
|
||||
while (index == MAP_FULL) {
|
||||
if (_hashmap_rehash(m) == MAP_OMEM)
|
||||
return MAP_OMEM;
|
||||
index = _hashmap_hash(m, key);
|
||||
}
|
||||
|
||||
m->data[index] = (struct hashmap_elem) {key, 1, value};
|
||||
m->curr_size++;
|
||||
|
||||
return MAP_OK;
|
||||
}
|
||||
|
||||
int hashmap_get(map_t map, int key, void **ret_val)
|
||||
{
|
||||
int pos;
|
||||
int i;
|
||||
struct hashmap_map *m;
|
||||
|
||||
m = (struct hashmap_map *) map;
|
||||
pos = _hashmap_hash_int(m, key);
|
||||
i = 0;
|
||||
|
||||
while (i < m->max_size) {
|
||||
if (m->data[pos].key == key && m->data[pos].in_use) {
|
||||
*ret_val = m->data[pos].val;
|
||||
return MAP_OK;
|
||||
}
|
||||
|
||||
pos = (pos + 1) % m->max_size;
|
||||
i++;
|
||||
}
|
||||
|
||||
*ret_val = NULL;
|
||||
return MAP_MISSING;
|
||||
}
|
||||
|
||||
void hashmap_free(map_t map)
|
||||
{
|
||||
struct hashmap_map *m;
|
||||
|
||||
m = (struct hashmap_map *) map;
|
||||
free(m->data);
|
||||
free(m);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/* SPDX-License-Identifier: BSD-2 */
|
||||
|
||||
#ifndef _hashmap_h
|
||||
#define _hashmap_h
|
||||
|
||||
#define MAP_OK 0
|
||||
#define MAP_OMEM -1
|
||||
#define MAP_FULL -2
|
||||
#define MAP_MISSING -3
|
||||
|
||||
typedef void *map_t;
|
||||
|
||||
extern map_t hashmap_new(void);
|
||||
extern void hashmap_free(map_t map);
|
||||
|
||||
extern int hashmap_put(map_t map, int key, void *val);
|
||||
extern int hashmap_get(map_t map, int key, void **ret_val);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,18 @@
|
|||
// SPDX-License-Identifier: BSD-2
|
||||
|
||||
#include "hashmap.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char *saved_str = calloc(1, sizeof(char *));
|
||||
|
||||
map_t m = hashmap_new();
|
||||
hashmap_put(m, 2, "Salut");
|
||||
hashmap_get(m, 2, (void **) &saved_str);
|
||||
hashmap_free(m);
|
||||
|
||||
printf("%s\n", saved_str);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue