mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 20:58:22 +00:00
hashtables
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
objects := $(patsubst %.c,%.o,$(wildcard *.c))
|
||||
subdirs := stdio string
|
||||
subdirs := stdio string hashtable
|
||||
OBJPATH=$(OBJDIR)/include
|
||||
export
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _HASHTABLE_H_INCLUDE
|
||||
#define _HASHTABLE_H_INCLUDE
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct{
|
||||
void* next;
|
||||
char* key;
|
||||
void* val;
|
||||
} hashtableentry;
|
||||
|
||||
typedef struct{
|
||||
size_t size;
|
||||
hashtableentry* entries;
|
||||
} hashtable;
|
||||
|
||||
bool hashtable_init(hashtable*, size_t);
|
||||
bool hashtable_insert(hashtable*, char*, void*);
|
||||
bool hashtable_remove(hashtable*, char*);
|
||||
void* hashtable_get(hashtable*, char*);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
objects := $(patsubst %.c,%.o,$(wildcard *.c))
|
||||
subdirs :=
|
||||
OBJPATH=$(OBJDIR)/include/hashtable/
|
||||
export
|
||||
|
||||
all: $(subdirs) $(objects)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
mkdir -p $(OBJPATH)
|
||||
cp $@ $(OBJPATH)/$@
|
||||
@@ -0,0 +1,114 @@
|
||||
#include <hashtable.h>
|
||||
#include <string.h>
|
||||
#include <kernel/alloc.h>
|
||||
|
||||
// temporary for testing
|
||||
|
||||
size_t hash(char* ptr, size_t size){
|
||||
size_t hash = 0;
|
||||
for(size_t i = 0; i < size; ++i){
|
||||
hash += ptr[i] * 9;
|
||||
}
|
||||
|
||||
return hash % 883;
|
||||
|
||||
}
|
||||
|
||||
bool hashtable_init(hashtable* table, size_t size){
|
||||
table->entries = alloc(size*sizeof(hashtableentry));
|
||||
if(!table->entries) return false;
|
||||
table->size = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline hashtableentry* getentry(hashtable* table, char* key){
|
||||
size_t entryn = hash(key, strlen(key)) % table->size;
|
||||
|
||||
return &table->entries[entryn];
|
||||
}
|
||||
|
||||
bool hashtable_insert(hashtable* table, char* key, void* val){
|
||||
|
||||
|
||||
hashtableentry* entry = getentry(table, key);
|
||||
|
||||
char* keysave = alloc(strlen(key)+1);
|
||||
|
||||
memcpy(keysave, key, strlen(key)+1);
|
||||
|
||||
if(!keysave) return false;
|
||||
|
||||
if(entry->key){
|
||||
while(entry->next)
|
||||
entry = entry->next;
|
||||
|
||||
entry->next = alloc(sizeof(hashtableentry));
|
||||
|
||||
if(!entry->next){
|
||||
free(keysave);
|
||||
return false;
|
||||
}
|
||||
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
entry->key = keysave;
|
||||
entry->val = val;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool hashtable_remove(hashtable* table, char* key){
|
||||
|
||||
hashtableentry* entry = getentry(table, key);
|
||||
|
||||
if(!entry->key) return false;
|
||||
|
||||
hashtableentry* prev = NULL;
|
||||
|
||||
while(entry){
|
||||
if(!strcmp(entry->key, key))
|
||||
break;
|
||||
prev = entry;
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
if(!entry) return false;
|
||||
|
||||
if(prev){
|
||||
prev->next = entry->next;
|
||||
free(entry->key);
|
||||
free(entry);
|
||||
}
|
||||
else{
|
||||
if(entry->next){
|
||||
void* addr = entry->next;
|
||||
memcpy(entry, entry->next, sizeof(hashtableentry));
|
||||
free(addr);
|
||||
}
|
||||
else{
|
||||
memset(entry, 0, sizeof(hashtableentry));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void* hashtable_get(hashtable* table, char* key){
|
||||
|
||||
hashtableentry* entry = getentry(table, key);
|
||||
|
||||
if(!entry->key)
|
||||
return NULL;
|
||||
|
||||
while(entry && strcmp(entry->key, key))
|
||||
entry = entry->next;
|
||||
|
||||
if(!entry) return NULL;
|
||||
|
||||
return entry->val;
|
||||
}
|
||||
Reference in New Issue
Block a user