-
Notifications
You must be signed in to change notification settings - Fork 0
/
queue.c
105 lines (86 loc) · 1.98 KB
/
queue.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
/**
* Simple queue. Please #include this file in runtime.c
*/
struct queue_t* queue_make() {
struct queue_t* q = (struct queue_t*)malloc(sizeof(struct queue_t));
q->head = NULL;
q->tail = NULL;
return q;
}
int queue_free(struct queue_t* q) {
int i = 0;
while (q->head != NULL) {
i++;
void* e = queue_deq(q);
if (e != NULL) free(e);
}
log_debug("Queue @ %p freed.", (void*)q);
free(q);
return i;
}
void queue_enq(struct queue_t* q, void* payload) {
struct queue_node_t* node = (struct queue_node_t*)malloc(sizeof(struct queue_node_t));
node->payload = payload;
node->next = NULL;
/* empty queue */
if (q->head == NULL) {
q->head = node;
q->tail = node;
return;
}
q->tail->next = node;
q->tail = node;
}
void* queue_deq(struct queue_t* q) {
/* empty queue */
if (q->head == NULL) panic("Empty queue.");
/* one element */
if (q->head == q->tail) {
void* ret = q->head->payload;
free(q->head);
q->head = NULL;
q->tail = NULL;
return ret;
}
/* more elements */
void* ret = q->head->payload;
struct queue_node_t* newhead = q->head->next;
free(q->head);
q->head = newhead;
return ret;
}
void* queue_ideq(struct queue_t* q, int i) {
if (i == 0) return queue_deq(q);
// Navigate to the one before i.
struct queue_node_t* cur = q->head;
while (cur != NULL && i > 1) {
cur = cur->next;
i--;
}
if (cur == NULL || cur->next == NULL) panic("Index out of range.");
assert(i == 1);
struct queue_node_t* tofree = cur->next;
void* payload = tofree->payload;
cur->next = tofree->next;
if (cur->next == NULL) q->tail = cur;
free(tofree);
return payload;
}
void queue_iforeach(struct queue_t* q, queue_fn f, void* env) {
struct queue_node_t* cur = q->head;
int i = 0;
while (cur != NULL) {
f(i, cur->payload, env);
i++;
cur = cur->next;
}
}
int queue_find (struct queue_t* q, void* addr) {
struct queue_node_t* cur = q->head;
int i = 0;
while (cur != NULL && cur->payload != addr) {
cur = cur->next;
i++;
}
return cur != NULL ? i : -1;
}