113 lines
2.6 KiB
C
113 lines
2.6 KiB
C
|
|
||
|
byte smap_key(const char *str) {
|
||
|
char start = str_lower(str[0]);
|
||
|
return ((start >= 'a') && (start <= 'z')) ? (start - 'a') : 26;
|
||
|
}
|
||
|
|
||
|
void smap_init(smap_t *map, uint load, byte cat) {
|
||
|
memset(map->elems, 0, sizeof(map->elems));
|
||
|
map->load = load;
|
||
|
map->cat = cat;
|
||
|
map->stored = 0;
|
||
|
}
|
||
|
|
||
|
byte smap_put(smap_t *map, const char *key, void *elem) {
|
||
|
byte k = smap_key(key);
|
||
|
void *list = map->elems[k];
|
||
|
uint size;
|
||
|
uint stored;
|
||
|
void **elems;
|
||
|
if(!list) {
|
||
|
map->elems[k] = list = mem_alloc(sizeof(void *) * map->load * 2 + sizeof(uint) * 2, map->cat);
|
||
|
memset(list, 0, sizeof(void *) * map->load * 2 + sizeof(uint) * 2);
|
||
|
((uint*)list)[0] = size = map->load;
|
||
|
stored = 0;
|
||
|
}
|
||
|
else {
|
||
|
size = ((uint*)list)[0];
|
||
|
stored = ((uint*)list)[1];
|
||
|
}
|
||
|
elems = (void**)(((uint*)list) + 2);
|
||
|
for(uint z = 0; z < size; z++) {
|
||
|
if((elems[z*2] != NULL) && str_eq_lower(key, (char*)(elems[z*2]))) {
|
||
|
elems[z*2+0] = (void*)key;
|
||
|
elems[z*2+1] = elem;
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
if(stored == size) {
|
||
|
map->elems[k] = list = mem_realloc(list, sizeof(void *) * (size+(map->load)) * 2 + sizeof(uint) * 2, map->cat);
|
||
|
elems = (void**)(((uint*)list) + 2);
|
||
|
memset(&elems[size*2], 0, sizeof(void *) * map->load * 2); // + sizeof(uint) * 2);
|
||
|
((uint*)list)[0] = size += map->load;
|
||
|
}
|
||
|
for(uint z = 0; z < size; z++) {
|
||
|
if(elems[z*2] == NULL) {
|
||
|
elems[z*2+0] = (void*)key;
|
||
|
elems[z*2+1] = elem;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
((uint*)list)[1] = stored + 1;
|
||
|
map->stored += 1;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
// void logd(const char *prefix, const char *fmt, ...);
|
||
|
|
||
|
void *smap_get(smap_t *map, const char *key) {
|
||
|
byte k = smap_key(key);
|
||
|
uint size;
|
||
|
void *list = map->elems[k];
|
||
|
void **elems;
|
||
|
if(!list) {
|
||
|
// logd("tst", "n: %d / %s", k, key);
|
||
|
return NULL;
|
||
|
}
|
||
|
size = ((uint*)list)[0];
|
||
|
elems = (void**)(((uint*)list) + 2);
|
||
|
for(uint z = 0; z < size; z++) {
|
||
|
if((elems[z*2] != NULL) && str_eq_lower(key, (char*)(elems[z*2+0]))) {
|
||
|
// logd("tst", "h: %d / %d / %s / %s / %s / %d", k, z, key, (char*)elems[z*2], (char*)elems[z*2+1], map->stored);
|
||
|
return elems[z*2+1];
|
||
|
}
|
||
|
}
|
||
|
// logd("tst", "l: %d / %s", k, key);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
void smap_clear(smap_t *map) {
|
||
|
map->stored = 0;
|
||
|
for(int z = 0; z < 27; z++) {
|
||
|
if(map->elems[z]) {
|
||
|
mem_free(map->elems[z]);
|
||
|
map->elems[z] = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void *smap_iter(smap_t *map, int *ptr) {
|
||
|
int k = (*ptr) >> 27;
|
||
|
int l = (*ptr) & 0x07ffffff;
|
||
|
void *list;
|
||
|
uint size;
|
||
|
void **elems;
|
||
|
void *elem;
|
||
|
for(; k < 27; k++) {
|
||
|
if(!(list = map->elems[k])) {
|
||
|
l = 0;
|
||
|
continue;
|
||
|
}
|
||
|
size = ((uint*)list)[0];
|
||
|
elems = (void**)(((uint*)list) + 2);
|
||
|
for(; l < size; l++) {
|
||
|
if(elem = elems[l*2+1]) {
|
||
|
*ptr = (k << 27) | (l + 1);
|
||
|
return elem;
|
||
|
}
|
||
|
}
|
||
|
l = 0;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|