planarbot/sortedmap.c

159 lines
3.2 KiB
C
Raw Normal View History

2022-11-01 22:09:32 +01:00
#include "sortedmap.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
SortedMap * map() {
SortedMap *this = malloc(sizeof(SortedMap));
this->type = EMPTY;
this->key = NULL;
return this;
2022-11-01 22:09:32 +01:00
}
void * get_map(SortedMap *this, char *key) {
switch (this->type) {
case EMPTY:
return NULL;
case LEAF:
if (strcmp(key, this->key) == 0) return this->content.value;
2022-11-01 22:09:32 +01:00
return NULL;
case INTERN:
2022-11-01 22:09:32 +01:00
if (strcmp(key, this->key) <= 0) {
return get_map(this->content.children.l, key);
2022-11-01 22:09:32 +01:00
} else {
return get_map(this->content.children.r, key);
2022-11-01 22:09:32 +01:00
}
default:
return NULL;
2022-11-01 22:09:32 +01:00
}
}
SortedMap * put_map(SortedMap *this, char *key, void *value) {
SortedMap *leaf, *intern;
int cmp = this->key != NULL ? strcmp(key, this->key) : 0;
switch (this->type) {
case EMPTY:
this->type = LEAF;
this->key = key;
this->content.value = value;
return this;
case LEAF:
if (cmp == 0) {
this->content.value = value;
return this;
}
leaf = malloc(sizeof(SortedMap));
2022-11-01 22:09:32 +01:00
leaf->type = LEAF;
leaf->key = key;
leaf->content.value = value;
intern = malloc(sizeof(SortedMap));
intern->type = INTERN;
intern->key = this->key;
intern->content.children.l = cmp < 0 ? leaf : this;
intern->content.children.r = cmp < 0 ? this : leaf;
return intern;
case INTERN:
if (cmp <= 0) {
this->content.children.l = put_map(this->content.children.l, key, value);
return this;
2022-11-01 22:09:32 +01:00
} else {
this->content.children.r = put_map(this->content.children.r, key, value);
return this;
2022-11-01 22:09:32 +01:00
}
default:
return NULL;
2022-11-01 22:09:32 +01:00
}
}
void print_indent_(int indent) {
int i;
for(i = 0; i < indent; i++) printf(" ");
}
void print_map_(SortedMap *this, int indent) {
switch (this->type) {
case EMPTY:
printf("empty\n");
break;
case LEAF:
2022-11-01 22:09:32 +01:00
print_indent_(indent);
printf("%s: %s\n", this->key, (char *) this->content.value);
break;
case INTERN:
print_map_(this->content.children.r, indent + 1);
2022-11-01 22:09:32 +01:00
print_indent_(indent);
printf("%s\n", this->key);
print_map_(this->content.children.l, indent + 1);
break;
2022-11-01 22:09:32 +01:00
}
}
void print_map(SortedMap *this) {
print_map_(this, 0);
}
void * fold_map(SortedMap *this, void * init, void * (*f)(void * acc, char *key, void *value)) {
switch (this->type) {
case EMPTY:
return init;
case LEAF:
return f(init, this->key, this->content.value);
case INTERN:
2022-11-08 23:31:00 +01:00
return fold_map(this->content.children.r, fold_map(this->content.children.l, init, f), f);
default:
return NULL;
}
2022-11-01 22:09:32 +01:00
}
void free_mapvalues(SortedMap *this) {
switch (this->type) {
case EMPTY:
break;
case LEAF:
free(this->content.value);
break;
case INTERN:
free_mapvalues(this->content.children.l);
free_mapvalues(this->content.children.r);
break;
2022-11-01 22:09:32 +01:00
}
}
2022-11-08 23:31:00 +01:00
void free_mapkeys(SortedMap *this) {
switch (this->type) {
case EMPTY:
break;
case LEAF:
free(this->key);
break;
case INTERN:
free_mapkeys(this->content.children.l);
free_mapkeys(this->content.children.r);
break;
}
}
void * free_mappair(void *acc, char *key, void *value) {
free(key);
free(value);
return NULL;
}
void * free_mapitem(void *acc, char *key, void *value) {
free(value);
return NULL;
}
2022-11-01 22:09:32 +01:00
void free_map(SortedMap *this) {
switch (this->type) {
case EMPTY:
case LEAF:
free(this);
break;
case INTERN:
free_map(this->content.children.l);
free_map(this->content.children.r);
2022-11-01 22:09:32 +01:00
free(this);
break;
2022-11-01 22:09:32 +01:00
}
}