#include "main.h" #include "listhash.h" struct list_head *list_add(struct list_t *list, void *data, size_t size) { struct list_head *cur = list->end; struct list_head *new = xmalloc(sizeof(struct list_head)); new->data = xmalloc(size); new->next = NULL; if(DEBUG) {fprintf(stderr,"list_add; list:%p, data:%p, size:%d\n",list,data,size);} memcpy(new->data,data,size); if(cur == NULL) { new->prev = NULL; list->begin = new; list->end = new; } else { cur->next = new; new->prev = cur; list->end = new; } ++(list->count); if(new->data == NULL) { fprintf(stderr,"list_add, emiting list_head with data == NULL\n"); } return new; } void *list_del_nf(struct list_t *list, struct list_head *item) { struct list_head *cur; void *temp; if(DEBUG) {fprintf(stderr,"list_del_nf; list:%p, item:%p\n",list,item);} cur = item->prev; if(cur == NULL) { list->begin = item->next; if(item->next != NULL) { item->next->prev = NULL; } } else { cur->next = item->next; if(item->next != NULL) { item->next->prev = cur; } } if(item == list->end) { list->end = item->prev; } temp = item->data; free(item); --(list->count); if(temp == NULL) { fprintf(stderr,"list_del_nf: returning NULL\n"); } return temp; } void list_del(struct list_t *list, struct list_head *item) { void *p; p = list_del_nf(list,item); free(p); } void list_init(struct list_t *list) { list->begin = NULL; list->end = NULL; //list->current = NULL; list->count = 0; } void list_do(struct list_t *list, void (*function)(void *data)) { /* * the old value is a safety net, as the function may change the * list while we are moving through it, e.g. delete */ struct list_head *old = NULL; struct list_head *cur = list->begin; while(cur != NULL) { old = cur; cur = cur->next; //fprintf(stderr,"list_do: cur:%p\n",cur); function(old->data); } } hash_t hash(void *in, unsigned int length) { unsigned int i; char *p = (char *)in; hash_t ha = 0; for(i = 0; i < length; ++i) { ha = ha * 37 + (int)*(p+i); } return (ha % HASHSIZE); } void hash_table_init(struct hash_table *t) { unsigned int i; for(i = 0; i < HASHSIZE; ++i) { t->table[i] = NULL; } } void *hash_find(struct hash_table *tab, hash_t ha, unique_t uni) { struct hash_bucket *row; void *ret = NULL; row = tab->table[ha]; if(row != NULL) { if(row->next == NULL) { ret = row->data; } else { while(row->unique != uni && row != NULL) { row = row->next; } if(row != NULL) { ret = row->data; } } } if(DEBUG) {fprintf(stderr,"hash_find: ret:%p\n",ret);} return ret; } void *hash_findu(struct hash_table *tab, unique_t uni) { hash_t ha = hash(&uni,sizeof(unique_t)); return hash_find(tab,ha,uni); } void *hash_add_ncp(struct hash_table *tab, unique_t uni, void *data) { struct hash_bucket *new; struct hash_bucket *cur; hash_t ha; if(DEBUG) {fprintf(stderr,"hash_add_cnp; tab:%p, uni:%x, data:%p\n",tab,uni,data);} ha = hash(&uni,sizeof(unique_t)); if(DEBUG) {fprintf(stderr,"hash_add_cnp; ha: %x\n",ha);} new = xmalloc(sizeof(struct hash_bucket)); new->unique = uni; new->next = NULL; new->data = data; cur = tab->table[ha]; if(cur == NULL) { tab->table[ha] = new; } else { while(cur->next != NULL) { cur = cur->next; } cur->next = new; } return new->data; } void *hash_add(struct hash_table *tab, unique_t uni, void *data, size_t datasize) { void *cp = xmalloc(datasize); memcpy(cp,data,datasize); return hash_add_ncp(tab,uni,cp); } void hash_del(struct hash_table *tab, hash_t ha, unique_t uni) { struct hash_bucket *old = NULL; struct hash_bucket *cur = NULL; if(DEBUG) {fprintf(stderr,"hash_del; tab:%p, ha:%x, uni:%x\n",tab,ha,uni);} cur = tab->table[ha]; while(cur != NULL) { if(cur->unique == uni) { break; } old = cur; cur = cur->next; } if(cur != NULL) { if(old != NULL) { old->next = cur->next; } else { tab->table[ha] = cur->next; } free(cur->data); free(cur); } } void *hash_add_lose(struct hash_table *tab, unique_t uni, void *data, size_t datasize) { struct hash_bucket *new; struct hash_bucket *cur; hash_t ha; if(DEBUG) {fprintf(stderr,"hash_add_lose; tab:%p, uni:%x, data:%p, datasize:%d\n",tab,uni,data,datasize);} ha = hash(&uni,sizeof(unique_t)); if(DEBUG) {fprintf(stderr,"hash_add_lose; ha: %x\n",ha);} new = xmalloc(sizeof(struct hash_bucket)); new->unique = uni; new->next = NULL; new->data = xmalloc(datasize); memcpy(new->data,data,datasize); cur = tab->table[ha]; if(cur == NULL) { tab->table[ha] = new; } else { free(tab->table[ha]->data); free(tab->table[ha]); tab->table[ha] = new; } return new->data; }