aboutsummaryrefslogtreecommitdiff
path: root/src/types
diff options
context:
space:
mode:
Diffstat (limited to 'src/types')
-rw-r--r--src/types/map.c106
-rw-r--r--src/types/map.h3
2 files changed, 73 insertions, 36 deletions
diff --git a/src/types/map.c b/src/types/map.c
index b5afc1c..cd46537 100644
--- a/src/types/map.c
+++ b/src/types/map.c
@@ -10,52 +10,74 @@ uint64_t hash(char* c, size_t len){
return fnv_1((uint8_t*)c, len, v_a);
}
-map_t* map_init(){
- map_t* awa = malloc(sizeof * awa);
- awa->M = malloc(sizeof * awa->M * 4);
+void map_dump(map_t* M){
+ printf("---\n%i %i\n- **\n",M->mod, M->len);
+ for(int i = 0; i != M->mod; i++){
+ if(M->M[i].used){
+ printf("%i | %s : %p\n",i,M->M[i].key->c, M->M[i].value);
+ }
+ }
+}
+
+map_t* map_initl(size_t len){
+ map_t* awa = calloc(sizeof * awa, 1);
+ awa->M = calloc(sizeof * awa->M, len);
+ //for(int i = 0; i != len; i++) awa->M[i].used = 0;
awa->len = 0;
- awa->mod = 4;
+ awa->mod = len;
return awa;
}
-void map_regraph(map_t* M){
- map_t* remade = map_init();
- for(int i = 0; i != M->len; i++){
+map_t* map_init(){
+ return map_initl(4);
+}
+
+void map_expand(map_t** _M){
+ map_t* M = *_M;
+ map_t* remade = map_initl(M->mod * 4);
+ for(int i = 0; i != M->mod; i++){
//what happens if the map_set calls map_regraph??? idk
- map_set(remade, M->M[i].key->c, M->M[i].value);
+ if(M->M[i].used)
+ map_set(&remade, M->M[i].key->c, M->M[i].value);
}
- M = remade;
+
+ *_M = remade;
}
-void map_set(map_t* M, char* key, void* value){
+void map_set(map_t** _M, char* key, void* value){
+ map_t* M = *_M;
uint64_t h = hash(key, strlen(key));
- if(M->len >= M->mod){
+
+ if(M->len + 1 >= M->mod){
expand:
- M->mod *= 4;
- M->M = realloc(M->M, sizeof * M->M * M->mod);
- //regraph it
- map_regraph(M);
+ map_expand(&M);
}
uint64_t ind = h % M->mod;
-
- for(int count = 0; M->M[ind].key != NULL && M->M[ind].hash != h && strcmp(M->M[ind].key->c, key) != 0; count++){
+ uint64_t oind = ind;
+
+ //iterates until there is a free space
+ for(int count = 0; M->M[ind].used && M->M[ind].hash != h && strcmp(M->M[ind].key->c, key) != 0; count++){
ind++;
if(ind >= M->mod) ind = 0;
- if(count > 5) goto expand;
+ if(ind == oind || count > 10) goto expand;
}
M->M[ind].hash = h;
M->M[ind].key = str_init(key);
M->M[ind].value = value;
+ M->M[ind].used = 1;
+ M->len++;
+
+ *_M = M;
}
int map_geti(map_t* M, char* key){
uint64_t h = hash(key, strlen(key));
uint64_t ind = h % M->mod;
- //melem_t sel = M->M[];
for(uint64_t initial = ind; ind != initial - 1;){
if(M->M[ind].key == NULL) return -1;
+ //printf("%s\n",M->M[ind].key->c);
if(M->M[ind].hash == h && strcmp(M->M[ind].key->c, key)==0) return ind;
ind++;
if(ind >= M->mod) ind = 0;
@@ -65,35 +87,49 @@ int map_geti(map_t* M, char* key){
void* map_get(map_t* M, char* key){
int r = map_geti(M, key);
- printf("%i\n",r);
+ //printf("%i\n",r);
return r == -1? NULL : M->M[r].value;
}
-void map_remove(map_t* p, char* key, enum free_type free);
-void map_clear(map_t*, enum free_type);
-void map_lclear(map_t*);
+void map_remove(map_t* p, char* key, enum free_type free){
+ int ind = map_geti(p, key);
+ if(ind == -1) return;
+ p->M[ind].used = 0;
+ p->M[ind].hash = 0;
+ str_free(p->M[ind].key);
+ free_method(p->M[ind].value, free);
+}
-void map_dump(map_t* M){
+void map_lclear(map_t* M){
+ free(M->M);
+ free(M);
+}
+
+void map_clear(map_t* M, enum free_type free){
for(int i = 0; i != M->mod; i++){
- if(M->M[i].key != NULL){
- printf("%i | %s : %p\n",i,M->M[i].key->c, M->M[i].value);
- }
+ if(M->M[i].used){
+ str_free(M->M[i].key);
+ free_method(M->M[i].value, free);
+ }
}
+ map_lclear(M);
}
+
int main(){
int i = 5;
int b = 24;
int c = 9;
map_t* m = map_init();
- for(int i = 65; i != 91; i++){
- //printf("%c\n",i);
- int* ww = malloc(sizeof * ww * 55);
- ww[0] = i;
- map_set(m, ((char[]){i, 0}), ww);
- }
- map_dump(m);
- printf("%i\n",*(int*)map_get(m, "B"));
+ map_set(&m, "wowa", &b);
+ printf("%i\n",*(int*)map_get(m, "wowa"));
+ map_set(&m, "aw", &i);
+ map_set(&m, "awc", &i);
+ map_set(&m, "awa", &i);
+ map_set(&m, "aww", &i);
+ printf("%i\n",*(int*)map_get(m, "wowa"));
+
+ map_clear(m, NONE);
return 0;
} \ No newline at end of file
diff --git a/src/types/map.h b/src/types/map.h
index cb8fed2..efa6d65 100644
--- a/src/types/map.h
+++ b/src/types/map.h
@@ -10,6 +10,7 @@ typedef struct {
void* value;
str* key;
uint64_t hash;
+ int used;
} melem_t;
typedef struct {
@@ -19,7 +20,7 @@ typedef struct {
} map_t;
map_t* map_init();
-void map_set(map_t*, char*, void*);
+void map_set(map_t**, char*, void*);
void* map_get(map_t* , char*);
int map_geti(map_t* , char*);
void map_remove(map_t* p, char* key, enum free_type free);