int pq_put( priority_queue_t *q, void *e ) { int i; if( q->size == q->count ) { void **old_arr = q->arr; int old_size = q->size; q->size = maxi( 4, 2*q->size ); q->arr = (void **)realloc( q->arr, sizeof(void*)*q->size ); if( q->arr == 0 ) { oom_handler( q ); q->arr = old_arr; q->size = old_size; return 0; } } i = q->count; while( (i>0) && (q->compare( q->arr[(i-1)/2], e )<0 ) ) { q->arr[i] = q->arr[(i-1)/2]; i = (i-1)/2; } q->arr[i]=e; q->count++; return 1; }
void hash_init2( hash_table_t *h, int (*hash_func)(void *key), int (*compare_func)(void *key1, void *key2), size_t capacity) { int i; size_t sz = 32; while( sz < (capacity*4/3) ) sz*=2; /* Make sure the size is a Mersenne number. Should hopfully be a reasonably good size with regard to avoiding patterns of collisions. */ sz--; h->arr = malloc( sizeof(hash_struct_t)*sz ); if( !h->arr ) { oom_handler( h ); return; } h->size = sz; for( i=0; i< sz; i++ ) h->arr[i].key = 0; h->count=0; h->hash_func = hash_func; h->compare_func = compare_func; h->cache=-1; }
/** Reallocate the queue_t */ static int q_realloc( dyn_queue_t *q ) { void **old_start = q->start; void **old_stop = q->stop; int diff; int new_size; new_size = 2*(q->stop-q->start); q->start=(void**)realloc( q->start, sizeof(void*)*new_size ); if( !q->start ) { q->start = old_start; oom_handler( q ); return 0; } diff = q->start - old_start; q->get_pos += diff; q->stop = &q->start[new_size]; memcpy( old_stop + diff, q->start, sizeof(void*)*(q->get_pos-q->start)); q->put_pos = old_stop + diff + (q->get_pos-q->start); return 1; }
static /*@only@*/ char *xstrdup(const char* s) { char* new_str; assert(s != NULL); assert(strlen(s) < MAX_ALLOC_SIZE); new_str = strdup(s); if (new_str == NULL) oom_handler(); return new_str; }
static /*@only@*/ /*@out@*/ void *xmalloc(size_t size) { void* ptr; assert(size < MAX_ALLOC_SIZE); ptr = malloc(size); if (ptr == NULL) oom_handler(); return ptr; }
void q_init( dyn_queue_t *q ) { q->start = (void **)malloc( sizeof(void*)*1 ); if( !q->start ) { oom_handler( q ); return; } q->stop = &q->start[1]; q->put_pos = q->get_pos = q->start; }
array_list_t *al_new() { array_list_t *res = malloc( sizeof( array_list_t ) ); if( !res ) { oom_handler( 0 ); return 0; } al_init( res ); return res; }
static int al_push_generic( array_list_t *l, anything_t o ) { if( l->pos >= l->size ) { int new_size = l->pos == 0 ? MIN_SIZE : 2 * l->pos; void *tmp = realloc( l->arr, sizeof( anything_t )*new_size ); if( tmp == 0 ) { oom_handler( l ); return 0; } l->arr = tmp; l->size = new_size; } l->arr[l->pos++] = o; return 1; }
int al_insert( array_list_t *a, int pos, int count ) { assert( pos >= 0 ); assert( count >= 0 ); assert( a ); if( !count ) return 0; /* Reallocate, if needed */ if( maxi( pos, a->pos) + count > a->size ) { /* If we reallocate, add a few extra elements just in case we want to do some more reallocating any time soon */ size_t new_size = maxi( maxi( pos, a->pos ) + count +32, a->size*2); void *tmp = realloc( a->arr, sizeof( anything_t )*new_size ); if( tmp ) { a->arr = tmp; } else { oom_handler( a ); return 0; } } if( a->pos > pos ) { memmove( &a->arr[pos], &a->arr[pos+count], sizeof(anything_t ) * (a->pos-pos) ); } memset( &a->arr[pos], 0, sizeof(anything_t)*count ); a->pos += count; return 1; }
/** Reallocate the hash array. This is quite expensive, as every single entry has to be rehashed and moved. */ static int hash_realloc( hash_table_t *h, int sz ) { /* Avoid reallocating when using pathetically small tables */ if( ( sz < h->size ) && (h->size < HASH_MIN_SIZE)) return 1; sz = maxi( sz, HASH_MIN_SIZE ); hash_struct_t *old_arr = h->arr; int old_size = h->size; int i; h->cache = -1; h->arr = malloc( sizeof( hash_struct_t) * sz ); if( h->arr == 0 ) { h->arr = old_arr; oom_handler( h ); return 0; } memset( h->arr, 0, sizeof( hash_struct_t) * sz ); h->size = sz; for( i=0; i<old_size; i++ ) { if( old_arr[i].key != 0 ) { int pos = hash_search( h, old_arr[i].key ); h->arr[pos].key = old_arr[i].key; h->arr[pos].data = old_arr[i].data; } } free( old_arr ); return 1; }