X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=lib%2Fq.c;h=1d27b4238ce810113c649a33ac0668096bb4b8ba;hp=615f2fe252cdaef1911b0b62183e4307eaf3f34a;hb=fec1ab31707e68c2396b186e0e4928632402d649;hpb=e4687b3aa2aed49fb16ba9e9561344d808750297 diff --git a/lib/q.c b/lib/q.c index 615f2fe..1d27b42 100644 --- a/lib/q.c +++ b/lib/q.c @@ -197,35 +197,62 @@ void ringbuffer_clear(ringbuffer_t*r) // ------------------------------- heap_t ------------------------------- -void heap_init(heap_t*h,int n,int elem_size, int(*compare)(const void *, const void *)) +void heap_init(heap_t*h,int elem_size, int(*compare)(const void *, const void *)) { memset(h, 0, sizeof(heap_t)); - h->max_size = n; h->size = 0; h->elem_size = elem_size; h->compare = compare; - h->elements = (void**)rfx_calloc(n*sizeof(void*)); - h->data = (char*)rfx_calloc(h->max_size*h->elem_size); + h->elements = 0; + h->max_size = 0; +} +heap_t* heap_new(int elem_size, int(*compare)(const void *, const void *)) +{ + heap_t*h = malloc(sizeof(heap_t)); + heap_init(h, elem_size, compare); + return h; +} +heap_t* heap_clone(heap_t*o) +{ + heap_t*h = malloc(sizeof(heap_t)); + memcpy(h, o, sizeof(heap_t)); + h->elements = rfx_alloc(sizeof(void*)*h->size); + int t; + for(t=0;tsize;t++) { + h->elements[t] = rfx_alloc(h->elem_size); + memcpy(h->elements[t], o->elements[t], h->elem_size); + } + return h; } void heap_clear(heap_t*h) { + int t; + for(t=0;tsize;t++) { + rfx_free(h->elements[t]); + h->elements[t]=0; + } rfx_free(h->elements); - rfx_free(h->data); +} +void heap_destroy(heap_t*h) +{ + heap_clear(h); + free(h); } -#define HEAP_NODE_SMALLER(h,node1,node2) ((h)->compare((node1),(node2))>0) +#define HEAP_NODE_LARGER(h,node1,node2) ((h)->compare((node1),(node2))>0) +#define HEAP_NODE_SMALLER(h,node1,node2) ((h)->compare((node1),(node2))<0) static void up(heap_t*h, int node) { void*node_p = h->elements[node]; int parent = node; + int tmp = node; do { node = parent; if(!node) break; parent = (node-1)/2; h->elements[node] = h->elements[parent]; - } while(HEAP_NODE_SMALLER(h,h->elements[parent], node_p)); - + } while(HEAP_NODE_SMALLER(h, h->elements[parent], node_p)); h->elements[node] = node_p; } static void down(heap_t*h, int node) @@ -250,20 +277,32 @@ static void down(heap_t*h, int node) void heap_put(heap_t*h, void*e) { int pos = h->size++; - memcpy(&h->data[pos*h->elem_size],e,h->elem_size); - h->elements[pos] = &h->data[pos]; + void*data = rfx_alloc(h->elem_size); + memcpy(data,e,h->elem_size); + + if(pos>=h->max_size) { + h->max_size = h->max_size<15?15:(h->max_size+1)*2-1; + h->elements = (void**)rfx_realloc(h->elements, h->max_size*sizeof(void*)); + assert(posmax_size); + } + + h->elements[pos] = data; up(h, pos); } int heap_size(heap_t*h) { return h->size; } -void* heap_max(heap_t*h) +void* heap_peek(heap_t*h) { + if(!h || !h->size) + return 0; return h->elements[0]; } void* heap_chopmax(heap_t*h) { + if(!h->size) + return 0; void*p = h->elements[0]; h->elements[0] = h->elements[--h->size]; down(h,0); @@ -282,7 +321,7 @@ void heap_dump(heap_t*h, FILE*fi) } void** heap_flatten(heap_t*h) { - void**nodes = (void**)rfx_alloc(h->size*sizeof(void*)); + void**nodes = (void**)rfx_alloc((h->size+1)*sizeof(void*)); void**p = nodes; while(h->size) { @@ -291,6 +330,7 @@ void** heap_flatten(heap_t*h) printf("\n");*/ *p++ = heap_chopmax(h); } + *p++ = 0; return nodes; } @@ -484,13 +524,14 @@ void trie_rollback(trie_t*t) // ------------------------------- crc32 -------------------------------------- -static unsigned int*crc32 = 0; +static unsigned int crc32[256]; +static char crc32_initialized=0; static void crc32_init(void) { int t; - if(crc32) + if(crc32_initialized) return; - crc32= (unsigned int*)rfx_alloc(sizeof(unsigned int)*256); + crc32_initialized = 1; for(t=0; t<256; t++) { unsigned int c = t; int s; @@ -603,14 +644,12 @@ char* string_escape(string_t*str) unsigned int crc32_add_byte(unsigned int checksum, unsigned char b) { - if(!crc32) - crc32_init(); + crc32_init(); return checksum>>8 ^ crc32[(b^checksum)&0xff]; } unsigned int crc32_add_string(unsigned int checksum, const char*s) { - if(!crc32) - crc32_init(); + crc32_init(); if(!s) return checksum; while(*s) { @@ -624,8 +663,7 @@ unsigned int string_hash(const string_t*str) { int t; unsigned int checksum = 0; - if(!crc32) - crc32_init(); + crc32_init(); for(t=0;tlen;t++) { checksum = checksum>>8 ^ crc32[(str->str[t]^checksum)&0xff]; } @@ -635,8 +673,7 @@ unsigned int string_hash2(const char*str) { unsigned int checksum = 0; const char*p = str; - if(!crc32) - crc32_init(); + crc32_init(); while(*p) { checksum = checksum>>8 ^ crc32[(*p^checksum)&0xff]; p++; @@ -990,6 +1027,10 @@ dictentry_t* dict_put(dict_t*h, const void*key, void* data) { unsigned int hash = h->key_type->hash(key); dictentry_t*e = (dictentry_t*)rfx_alloc(sizeof(dictentry_t)); + + if(!h->hashsize) + dict_expand(h, 1); + unsigned int hash2 = hash % h->hashsize; e->key = h->key_type->dup(key); @@ -1100,7 +1141,7 @@ char dict_del(dict_t*h, const void*key) while(e) { if(h->key_type->equals(e->key, key)) { dictentry_t*next = e->next; - rfx_free((void*)e->key); + h->key_type->free(e->key); memset(e, 0, sizeof(dictentry_t)); rfx_free(e); if(e == head) { @@ -1197,6 +1238,8 @@ void dict_destroy_shallow(dict_t*dict) void dict_destroy(dict_t*dict) { + if(!dict) + return; dict_clear(dict); rfx_free(dict); }