-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathheap.c
181 lines (162 loc) · 4.62 KB
/
heap.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "heap.h"
#define noMUTEX_DEBUG
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
struct Heap *heap_create(int maxsize, void (*callback_events_queue)(int flag))
{
struct Heap *heap_ptr=NULL;
if(pthread_mutex_init(&mutex, NULL))
exit(2);
heap_ptr = malloc(sizeof(struct Heap));
if (heap_ptr)
{
heap_ptr->maxsize = maxsize;
heap_ptr->count_items = 0;
heap_ptr->callback_events_queue = callback_events_queue;
heap_ptr->items = malloc(sizeof(struct Heap_item) * maxsize );
if (!heap_ptr->items)
{
exit(1);
}
// memset(heap_ptr->items, -1, sizeof(struct Heap_item) * maxsize);
return heap_ptr;
}
else
exit(1);
}
void heap_free(struct Heap *h)
{
free(h->items);
free(h);
}
static void heap_swap(struct Heap_item *first, struct Heap_item *second)
{
struct Heap_item tmp = *first;
*first = *second;
*second = tmp;
}
struct Heap_item heap_max(const struct Heap *heap)
{
int res=0;
struct Heap_item ret_item = {-1,0, NULL};
#ifdef MUTEX_DEBUG
printf("heap_max mutex lock \n ");
#endif
pthread_mutex_lock(&mutex);
if (heap->count_items > 0)
{
ret_item = heap->items[1];
}
else
printf("Heap is empty\n");
pthread_mutex_unlock(&mutex);
#ifdef MUTEX_DEBUG
printf("heap_max mutex unlock \n ");
#endif
return ret_item;
}
void heap_display(struct Heap *heap) {
int i;
#ifdef MUTEX_DEBUG
printf("heap_display mutex lock \n ");
#endif
pthread_mutex_lock(&mutex);
printf("Queue: ");
for(i=0; i<=heap->count_items; ++i) {
printf("%d ", heap->items[i].priority);
}
printf("\n");
pthread_mutex_unlock(&mutex);
#ifdef MUTEX_DEBUG
printf("heap_display mutex unlock \n ");
#endif
}
int heap_insert(struct Heap *heap, int priority, char *value, const unsigned long thread_id)
{
int i=0;
struct Heap_item *tmp=NULL;
#ifdef MUTEX_DEBUG
printf("heap_insert mutex lock \n ");
#endif
pthread_mutex_lock(&mutex);
if (heap->count_items >= heap->maxsize)
{
pthread_mutex_unlock(&mutex);
#ifdef MUTEX_DEBUG
printf("heap_insert mutex unlock \n ");
#endif
heap->callback_events_queue(HIGH_WATER_MARK);
return 1;
}
++heap->count_items;
heap->items[heap->count_items].priority = priority;
heap->items[heap->count_items].value = value;
heap->items[heap->count_items].thread_id = thread_id;
/* heapify, push to up*/
for (i = heap->count_items; i > 1 && heap->items[i].priority > heap->items[i/2].priority; i = i/2)
{
heap_swap(&heap->items[i], &heap->items[i/2]);
}
pthread_mutex_unlock(&mutex);
#ifdef MUTEX_DEBUG
printf("heap_insert mutex unlock \n ");
#endif
return 0;
}
int heap_removemax(struct Heap *heap, struct Heap_item *value)
{
int largest_index, leftChild;
int end_heap ;
#ifdef MUTEX_DEBUG
printf("heap_removemax mutex lock \n ");
#endif
pthread_mutex_lock(&mutex);
if(!heap->count_items)
{
pthread_mutex_unlock(&mutex);
#ifdef MUTEX_DEBUG
printf("heap_removemax mutex unlock \n ");
#endif
return 0;
}
end_heap = heap->count_items - 1;
heap_swap(&heap->items[1], &heap->items[heap->count_items]); //swap with head with last
for (largest_index = 1; 2*largest_index <= end_heap; largest_index = leftChild) //try to rebuild heap
{
leftChild = 2 * largest_index; //index for point out to leaves
if (leftChild < end_heap && heap->items[leftChild].priority < heap->items[leftChild + 1].priority)
{
leftChild++;
}
if (heap->items[largest_index].priority >= heap->items[leftChild].priority)
{
break;
}
heap_swap(&heap->items[largest_index], &heap->items[leftChild]);
}
*value = heap->items[heap->count_items--];
if(!heap->count_items)
heap->callback_events_queue(LOW_WATER_MARK);
pthread_mutex_unlock(&mutex);
#ifdef MUTEX_DEBUG
printf("heap_removemax mutex unlock \n ");
#endif
return 1;
}
unsigned int heap_size(struct Heap *heap)
{
int count=0;
#ifdef MUTEX_DEBUG
printf("heap_size mutex lock \n ");
#endif
pthread_mutex_lock(&mutex);
count = heap->count_items;
pthread_mutex_unlock(&mutex);
#ifdef MUTEX_DEBUG
printf("heap_size mutex unlock \n ");
#endif
return count;
}