Add the basic codebase to the repository
This commit is contained in:
parent
d55dc5847d
commit
b2f7c91f6a
6 changed files with 212 additions and 0 deletions
20
include/hashmap.h
Normal file
20
include/hashmap.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef __HASHMAP_HASHMAP_H
|
||||
#define __HASHMAP_HASHMAP_H
|
||||
|
||||
#include <linkedlist.h>
|
||||
|
||||
#define BUCKET_SIZE 64
|
||||
|
||||
struct hashmap {
|
||||
struct ll buckets[BUCKET_SIZE];
|
||||
};
|
||||
|
||||
struct hashmap new_map();
|
||||
void insert_map(struct hashmap *map, const char *key, const char *value);
|
||||
const char *lookup_map(struct hashmap *map, const char *key);
|
||||
int exists_map(struct hashmap *map, const char *key);
|
||||
const char *remove_map(struct hashmap *map, const char *key);
|
||||
void foreach_map(struct hashmap *map, void (*cb)(const char *key, const char *value));
|
||||
void print_map(struct hashmap *map);
|
||||
|
||||
#endif
|
16
include/linkedlist.h
Normal file
16
include/linkedlist.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef __HASHMAP_LINKEDLIST_H
|
||||
#define __HASHMAP_LINKEDLIST_H
|
||||
|
||||
#include <node.h>
|
||||
|
||||
struct ll {
|
||||
struct node *list;
|
||||
struct node *head;
|
||||
struct node *tail;
|
||||
};
|
||||
|
||||
struct new_ll();
|
||||
void insert_ll(struct ll *list, const char *key, const char *value);
|
||||
void remove_ll(struct ll *list, struct node *link);
|
||||
|
||||
#endif
|
14
include/node.h
Normal file
14
include/node.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef __HASHMAP_NODE_H
|
||||
#define __HASHMAP_NODE_H
|
||||
|
||||
struct node {
|
||||
struct node *next;
|
||||
struct node *prev;
|
||||
const char *key;
|
||||
const char *value;
|
||||
};
|
||||
|
||||
struct node *new_node(const char *key, const char *value);
|
||||
struct node *insert_node(struct node *entry, const char *key, const char *value);
|
||||
|
||||
#endif
|
98
src/hashmap.c
Normal file
98
src/hashmap.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
#include <hashmap.h>
|
||||
|
||||
struct hashmap new_map() {
|
||||
struct hashmap new;
|
||||
|
||||
for(int count = 0; count < BUCKET_SIZE; ++count) {
|
||||
new.buckets[count] = new_ll();
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
static unsigned int hash_map(const char *str) {
|
||||
unsigned int val = 0, high;
|
||||
|
||||
while (*str) {
|
||||
val = ( val << 4 ) + *str++;
|
||||
|
||||
if((high = val & 0xF0000000) != 0) {
|
||||
val ^= high >> 24;
|
||||
}
|
||||
|
||||
val &= ~high;
|
||||
}
|
||||
|
||||
return val % BUCKET_SIZE;
|
||||
}
|
||||
|
||||
void insert_map(struct hashmap *map, const char *key, const char *value) {
|
||||
if(key == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
int index = hash_map(key);
|
||||
|
||||
for(struct node *iter = map->buckets[index].head; iter != NULL; iter = iter->next) {
|
||||
if(strcmp(iter->key, key) == 0) {
|
||||
iter->value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
insert_ll(&map->buckets[index], key, value);
|
||||
}
|
||||
|
||||
const char *lookup_map(struct hashmap *map, const char *key) {
|
||||
if(key == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int index = hash_map(key);
|
||||
|
||||
for(struct node *iter = map->buckets[index].head; iter != NULL; iter = iter->next) {
|
||||
if(strcmp(iter->key, key) == 0) {
|
||||
return iter->value;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int exists_map(struct hashmap *map, const char *key) {
|
||||
return lookup_map(map, key) != NULL;
|
||||
}
|
||||
|
||||
const char *remove_map(struct hashmap *map, const char *key) {
|
||||
if(key == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int index = hash_map(key);
|
||||
|
||||
for(struct node *iter = map->buckets[index].head; iter != NULL; iter = iter->next) {
|
||||
if(strcmp(iter->key, key) == 0) {
|
||||
const char *value = iter->value;
|
||||
remove_ll(&map->buckets[index], iter);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void foreach_map(struct hashmap *map, void (*cb)(const char *key, const char *value)) {
|
||||
for(int count = 0; count < BUCKET_SIZE; ++count) {
|
||||
for(struct node *iter = map->buckets[count].head; iter != NULL; iter = iter->next) {
|
||||
cb(iter->key, iter->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void print_value_map(const char *key, const char *value) {
|
||||
printf("%s: %s\n", key, value);
|
||||
}
|
||||
|
||||
void print_map(struct hashmap *map) {
|
||||
foreach_map(map, &print_value_map);
|
||||
}
|
41
src/linkedlist.c
Normal file
41
src/linkedlist.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include <linkedlist.h>
|
||||
|
||||
struct ll new_ll() {
|
||||
struct ll new;
|
||||
new.list = NULL;
|
||||
new.head = NULL;
|
||||
new.tail = NULL;
|
||||
return new;
|
||||
}
|
||||
|
||||
void insert_ll(struct ll *list, const char *key, const char *value) {
|
||||
list->list = insert_node(list->tail, key, value);
|
||||
list->tail = list->list;
|
||||
|
||||
if(list->head == NULL) {
|
||||
list->head = list->list;
|
||||
}
|
||||
}
|
||||
|
||||
void remove_ll(struct ll *list, struct node *link) {
|
||||
if(link == list->head && link == list->tail) {
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
} else if(link == list->head) {
|
||||
list->head = list->head->next;
|
||||
list->head->prev = NULL;
|
||||
} else if(link == list->tail) {
|
||||
list->tail = list->tail->prev;
|
||||
list->tail->next = NULL;
|
||||
} else {
|
||||
link->prev->next = link->next;
|
||||
link->next->prev = link->prev;
|
||||
}
|
||||
|
||||
link->next = NULL;
|
||||
link->prev = NULL;
|
||||
link->key = NULL;
|
||||
link->value = NULL;
|
||||
free(link);
|
||||
link = NULL;
|
||||
}
|
23
src/node.c
Normal file
23
src/node.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include <node.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct node *new_node(const char *key, const char *value) {
|
||||
struct node *new = calloc(1, sizeof(struct node));
|
||||
new->next = NULL;
|
||||
new->prev = NULL;
|
||||
new->key = key;
|
||||
new->value = value;
|
||||
return new;
|
||||
}
|
||||
|
||||
struct node *insert_node(struct node *entry, const char *key, const char *value) {
|
||||
struct node *insert = new_node(key, value);
|
||||
insert->prev = entry;
|
||||
|
||||
if(entry != NULL) {
|
||||
insert->next = entry->next;
|
||||
entry->next = insert;
|
||||
}
|
||||
|
||||
return insert;
|
||||
}
|
Loading…
Reference in a new issue