@@ -5,21 +5,48 @@
55#include <stddef.h>
66#include <stdio.h>
77
8+void c_heap_free(CHeapItem * item)
9+{
10+ // fix links
11+ if (item->next != NULL)
12+ {
13+ item->next->prev_next = item->prev_next;
14+ }
15+ *(item->prev_next) = item->next;
16+
17+ // free payload
18+ item->finalizer(item->data);
19+
20+ // free item struct
21+ free(item);
22+}
23+
24+CHeapItem * c_heap_allocate(size_t size, CDataFinalizer_t * finalizer)
25+{
26+ void * data = (void *) malloc(size);
27+ return c_heap_create_item(data, finalizer);
28+}
29+
830CHeapItem * c_heap_create_item(void * data, CDataFinalizer_t * finalizer)
931{
1032 CHeapItem * item = (CHeapItem *) malloc(sizeof(CHeapItem));
1133
1234 item->data = data;
1335 item->finalizer = finalizer;
14− item->is_inserted = false;
1536 item->is_used = false;
1637 item->next = NULL;
38+ item->prev_next = NULL;
1739
1840 return item;
1941}
2042
21−void c_heap_insert(CHeap * heap, CHeapItem * item)
43+void c_heap_insert_if_needed(CHeap * heap, CHeapItem * item)
2244{
45+ if (item->prev_next != NULL) return; // already inserted
46+
47+ heap->first->prev_next = &item->next;
48+ item->prev_next = &heap->first;
49+
2350 item->next = heap->first;
2451 heap->first = item;
2552}
@@ -29,22 +56,14 @@ void c_heap_mark_item(CHeapItem * item)
2956 item->is_used = true;
3057}
3158
32−static void c_heap_free_item(CHeapItem * item)
33−{
34− item->finalizer(item->data);
35− free(item);
36−}
37−
3859void c_heap_sweep(CHeap * heap)
3960{
40− CHeapItem ** prev_next = &heap->first;
4161 CHeapItem * p = heap->first;
4262 while (p != NULL)
4363 {
4464 if (p->is_used)
4565 {
4666 p->is_used = false;
47− prev_next = &p->next;
4867 p = p->next;
4968 }
5069 else
@@ -52,8 +71,7 @@ void c_heap_sweep(CHeap * heap)
5271 CHeapItem * unused_item = p;
5372 p = p->next;
5473
55− *prev_next = unused_item->next;
56− c_heap_free_item(unused_item);
74+ c_heap_free(unused_item);
5775 }
5876 }
5977}
@@ -63,14 +81,11 @@ void c_heap_init(CHeap * heap)
6381 heap->first = NULL;
6482}
6583
66−void c_heap_free(CHeap * heap)
84+void c_heap_destroy(CHeap * heap)
6785{
68− CHeapItem * p = heap->first;
69− while (p != NULL)
86+ while (heap->first != NULL)
7087 {
71− CHeapItem * q = p;
72− p = p->next;
73− c_heap_free_item(q);
88+ c_heap_free(heap->first); // will update heap->first via the backward link
7489 }
7590}
7691