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; }