Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create an implementation of a generic map (#13) #31

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/lib/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ size_t list_size(struct list *l);
/** Places the first size number of elements of the list into the given array */
void list_to_array(struct list *l, void **buffer, size_t size);

#endif //_LIST_H_
#endif //_LIST_H_
39 changes: 27 additions & 12 deletions include/lib/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,39 @@

#include "stdlib/stdtypes.h"

/** Data structure for a generic map */
/** Structures for a generic map. */
struct entry {
Altanis marked this conversation as resolved.
Show resolved Hide resolved
/** The key associated with the entry. */
void *key;
/** The value associated with the entry. */
void *value;
};

struct map {
//TODO
/** Table which holds all entries. */
struct entry *table;
/** Amount of space used. */
size_t used;
/** Maximum space to allocate for entries */
size_t size;
};

/** Initializes a new hashtable */
void map_init(struct map *m);
/** Initializes a new hashmap. Returns `-1` if not allocated. */
int map_init(struct map *m, size_t size);
Altanis marked this conversation as resolved.
Show resolved Hide resolved
Altanis marked this conversation as resolved.
Show resolved Hide resolved

/** Frees the hashtable from memory */
/** Frees the hashtable from memory. */
void map_free(struct map *m);

/** Adds the key/value pair to the hashtable */
void map_put(struct map *m, void *key, void *value);
/** Adds the key/value pair to the hashtable. */
int map_put(struct map *m, void *key, void *value, size_t size);
Altanis marked this conversation as resolved.
Show resolved Hide resolved

/** Gets the value associated with the specified key. */
void *map_get(struct map *m, void *key, size_t size);

/** Gets the value associated with the specified key */
void *map_get(struct map *m, void *key);
/** Checks if key exists in hashmap. */
bool map_contains(struct map *m, void *key, size_t size);

/** Returns true if the hashtable contains the key, false otherwise */
bool map_contains(struct map *m, void *key);
Altanis marked this conversation as resolved.
Show resolved Hide resolved
/** Hash function for strings. */
size_t fnv_1a(char *str);
Altanis marked this conversation as resolved.
Show resolved Hide resolved

#endif //_MAP_H_
#endif //_MAP_H_
1 change: 1 addition & 0 deletions include/stdlib/stdtypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

/** Size type */
typedef unsigned int size_t;
typedef unsigned long long uint64_t;
Altanis marked this conversation as resolved.
Show resolved Hide resolved

#define NULL (void *) 0

Expand Down
2 changes: 1 addition & 1 deletion src/lib/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,4 @@ void list_to_array(struct list *l, void **buffer, size_t size) {
buffer[i++] = n->data;
n = n->next;
}
}
}
57 changes: 57 additions & 0 deletions src/lib/map.c
Original file line number Diff line number Diff line change
@@ -1,2 +1,59 @@
#include "lib/map.h"

size_t fnv_1a(char *ptr, size_t size) {
size_t hash = 0x811C9DC5;

for (;size--;) {
hash ^= ptr[size];
hash *= 0x01000193;
}

return hash;
}

int map_init(struct map *m, size_t size) {
m->table = calloc(size, sizeof(struct entry));
Altanis marked this conversation as resolved.
Show resolved Hide resolved
Altanis marked this conversation as resolved.
Show resolved Hide resolved
m->size = size;

/** Ensure map was allocated. */
if (m->table == NULL) return -1;
else return 0;
}

void map_free(struct map *m) {
free(m->table);
}

int map_put(struct map *m, void *key, void *value, size_t size) {
size_t idx = fnv_1a(key, size) % m->size;
size_t start = idx;


while (m->table[idx].key != NULL) {
idx = (++idx) % m->size;
if (idx == start) return -1;
Altanis marked this conversation as resolved.
Show resolved Hide resolved
if (memcmp(key, m->table[idx].key, size) == 0) break;
}

m->table[idx].key = key;
m->table[idx].value = value;
m->used++;

return 0;
}

void *map_get(struct map *m, void *key, size_t size) {
size_t idx = fnv_1a(key, size) % m->size;

if (m->table[idx].key == NULL) return NULL;
while (m->table[idx].key != NULL) {
if (memcmp(key, m->table[idx].key, size) == 0) return m->table[idx].value;
idx = (++idx) % m->size;
}

return NULL;
}

bool map_contains(struct map *m, void *k, size_t size) {
return map_get(m, k, size) != NULL;
}