first and last commit
This commit is contained in:
commit
c9e78fd810
381 changed files with 37141 additions and 0 deletions
201
map.h
Normal file
201
map.h
Normal file
|
@ -0,0 +1,201 @@
|
|||
|
||||
#define HASHM_BUCKETS 2
|
||||
|
||||
uint map_f_inthash(void *ptr) {
|
||||
uint hash = (uint)((ulong)ptr);
|
||||
return ((hash << 8) & 0xf000) | ((hash >> 8) & 0x0fff); // (hash >> 24) | ((hash >> 8) & 0x0000ff00) | ((hash << 8) & 0x00ff0000) | (hash << 24);
|
||||
}
|
||||
|
||||
byte map_f_inteq(void *ptr1, void *ptr2) {
|
||||
return ptr1 == ptr2;
|
||||
}
|
||||
|
||||
uint map_f_strhash(void *str) {
|
||||
int pos = 0;
|
||||
uint hash = 0;
|
||||
uint c;
|
||||
while(c = (uint)(((char*)str)[pos++])) {
|
||||
hash = 31 * hash + c;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
byte map_f_streq(void *str1, void *str2) {
|
||||
return strcmp((char*)str1, (char*)str2) == 0;
|
||||
}
|
||||
|
||||
void map_init(map_t *map, map_hashfunc *hash, map_eqfunc *eq, uint load, byte cat) {
|
||||
map->hash_func = hash;
|
||||
map->eq_func = eq;
|
||||
map->elems = NULL;
|
||||
map->load = load;
|
||||
map->cat = cat;
|
||||
map->stored = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
void **map_talloc(void ***ptr, byte offset) {
|
||||
void **list = *ptr;
|
||||
if(list == NULL) {
|
||||
*ptr = list = mem_alloc(sizeof(void **) * 256);
|
||||
memset(list, 0, sizeof(void **) * 256);
|
||||
}
|
||||
return list[offset];
|
||||
}
|
||||
*/
|
||||
|
||||
byte map_put(map_t *map, void *key, void *elem) {
|
||||
uint hash = map->hash_func(key);
|
||||
uint offset;
|
||||
uint size;
|
||||
void ***ptr = &map->elems;
|
||||
void **list = *ptr;
|
||||
void **elems;
|
||||
uint stored;
|
||||
for(int z = HASHM_BUCKETS - 1; z >= 0; z--) {
|
||||
offset = (hash >> (z << 3)) & 0xff;
|
||||
// list = *ptr;
|
||||
if(list == NULL) {
|
||||
*ptr = list = mem_alloc(sizeof(void **) * 256, map->cat);
|
||||
memset(list, 0, sizeof(void **) * 256);
|
||||
}
|
||||
ptr = (void***)&list[offset];
|
||||
list = list[offset];
|
||||
}
|
||||
if(list == NULL) {
|
||||
*ptr = 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) && map->eq_func(key, elems[z*2])) {
|
||||
elems[z*2+0] = key;
|
||||
elems[z*2+1] = elem;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(stored == size) {
|
||||
*ptr = 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] = key;
|
||||
elems[z*2+1] = elem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
((uint*)list)[1] = stored + 1;
|
||||
map->stored += 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *map_get(map_t *map, void *key) {
|
||||
uint hash = map->hash_func(key);
|
||||
uint offset;
|
||||
uint size;
|
||||
void **list = map->elems;
|
||||
void **elems;
|
||||
for(int z = HASHM_BUCKETS - 1; z >= 0; z--) {
|
||||
if(list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
offset = (hash >> (z << 3)) & 0xff;
|
||||
list = list[offset];
|
||||
}
|
||||
if(list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
size = ((uint*)list)[0];
|
||||
elems = (void**)(((uint*)list) + 2);
|
||||
for(uint z = 0; z < size; z++) {
|
||||
if((elems[z*2] != NULL) && map->eq_func(key, elems[z*2+0])) {
|
||||
return elems[z*2+1];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *map_remove(map_t *map, void *key) {
|
||||
uint hash = map->hash_func(key);
|
||||
uint offset;
|
||||
uint size;
|
||||
uint stored;
|
||||
void **lists[HASHM_BUCKETS];
|
||||
void **list = map->elems;
|
||||
void **elems;
|
||||
void *elem;
|
||||
int s;
|
||||
for(int z = HASHM_BUCKETS - 1; z >= 0; z--) {
|
||||
if(list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
offset = (hash >> (z << 3)) & 0xff;
|
||||
lists[z] = list;
|
||||
list = list[offset];
|
||||
}
|
||||
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) && map->eq_func(key, elems[z*2+0])) {
|
||||
elem = elems[z*2+1];
|
||||
elems[z*2+0] = elems[z*2+1] = NULL;
|
||||
((uint*)list)[1] = stored -= 1;
|
||||
// logd("t", "s %d", stored);
|
||||
if(stored == 0) {
|
||||
mem_free(list);
|
||||
for(int n = 0; n < HASHM_BUCKETS; n++) {
|
||||
// if(lists[n] == NULL) {
|
||||
// break;
|
||||
// }
|
||||
lists[n][(hash >> (n << 3)) & 0xff] = NULL;
|
||||
for(s = 0; s < 256; s++) {
|
||||
if(lists[n][s] != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(s == 256) {
|
||||
mem_free(lists[n]);
|
||||
if(n == HASHM_BUCKETS - 1) {
|
||||
map->elems = NULL;
|
||||
}
|
||||
else {
|
||||
lists[n+1][(hash >> ((n+1) << 3)) & 0xff] = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
map->stored -= 1;
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void map_rclear(void **list, int depth) {
|
||||
for(int z = 0; z < 256 && depth < HASHM_BUCKETS; z++) {
|
||||
if(list[z] != NULL) {
|
||||
map_rclear(list[z], depth+1);
|
||||
}
|
||||
}
|
||||
mem_free(list);
|
||||
}
|
||||
|
||||
void map_clear(map_t *map) {
|
||||
map->stored = 0;
|
||||
if(map->elems)
|
||||
map_rclear(map->elems, 0);
|
||||
map->elems = NULL;
|
||||
}
|
Reference in a new issue