#include #include #include #include "heap.h" /* Return a pointer to the next unused item on a heap */ void* new_from_heap(struct heap_t* heap) { /* Grow heap if necessary */ if (heap->count == heap->capacity) { int i; if (heap->step <= 0) return NULL; heap->capacity += heap->step; errno = 0; heap->data = realloc(heap->data, sizeof(void*) * heap->capacity); if (errno != 0) { /* Uh oh */ heap->capacity -= heap->step; return NULL; } for (i = heap->count; i < heap->capacity; i++) heap->data[i] = heap->alloc(heap->size); } return heap->data[heap->count++]; } /* Remove an item from a heap given its pointer */ int delete_from_heap(struct heap_t* heap, void* data) { int i; /* Find the index of the given data */ for (i = 0; i < heap->count && heap->data[i] != data; i++); /* Couldn't find it? */ if (i == heap->count) return 0; /* Remove the pointer and fill in the hole */ heap->count--; if (i < heap->count) { void* tmp = heap->data[i]; heap->data[i] = heap->data[heap->count]; heap->data[heap->count] = tmp; } return 1; } /* Call a function on all the data in a heap */ void process_heap(struct heap_t* heap, void (*proc)(void*)) { void** data = heap->data; void** data_end = data + heap->count; for (; data < data_end; data++) proc(*data); } /* Call a function on all the data in a heap given special arguments */ void process_heap_va(struct heap_t* heap, void (*proc)(void*, va_list), ...) { va_list ap; void** data = heap->data; void** data_end = data + heap->count; for (; data < data_end; data++) { va_start(ap, proc); proc(*data, ap); va_end(ap); } } /* Empty a heap (pointer array will be recycled) */ void empty_heap(struct heap_t* heap) { heap->count = 0; } /* Return a new heap */ struct heap_t* _create_heap(size_t size, int capacity, int step, void*(*alloc)(size_t), void(*dealloc)(void*)) { int i; struct heap_t* heap = malloc(sizeof(struct heap_t)); heap->data = capacity > 0 ? malloc(sizeof(void*) * capacity) : NULL; for (i = 0; i < capacity; i++) heap->data[i] = alloc(size); heap->count = 0; heap->capacity = capacity; heap->step = step; heap->size = size; heap->alloc = alloc; heap->dealloc = dealloc; return heap; } /* Destroy a heap */ void destroy_heap(struct heap_t* heap) { int i; for (i = 0; i < heap->capacity; i++) heap->dealloc(heap->data[i]); free(heap->data); heap->data = NULL; heap->count = 0; heap->capacity = 0; }