File: priorityqueue.h

package info (click to toggle)
ruby-ferret 0.11.8.4%2Bdebian-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 4,368 kB
  • sloc: ansic: 69,786; ruby: 8,131; makefile: 5
file content (155 lines) | stat: -rw-r--r-- 5,025 bytes parent folder | download | duplicates (4)
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
#ifndef FRT_PRIORITYQUEUE_H
#define FRT_PRIORITYQUEUE_H

#ifdef __cplusplus
extern "C" {
#endif

#include "global.h"

typedef bool (*frt_lt_ft)(const void *p1, const void *p2);

/**
 * A PriorityQueue has a fixed size and contains a less_than function and a
 * free_elem function specific to the data type to be stored in the queue.
 */
typedef struct FrtPriorityQueue
{
    int size;
    int capa;
    int mem_capa;
    void **heap;
    frt_lt_ft less_than_i;
    frt_free_ft free_elem_i;
} FrtPriorityQueue;

/**
 * Create a new PriorityQueue setting the less_than and free_elem for this
 * specific PriorityQueue.
 *
 * @param capa the capacity of the PriorityQueue. As more than the capacity is
 *   added to the queue the least valued elements drop off the bottom.
 * @param less_than the function to determine whether one value is less than
 *   another for this particular PriorityQueue
 * @param free_elem the function to free the elements in the PriorityQueue
 *   when it is destroyed or there is insertion overflow
 * @return a newly allocated PriorityQueue
 */
extern FrtPriorityQueue *frt_pq_new(int capa,
                                       frt_lt_ft less_than,
                                       frt_free_ft free_elem);

/**
 * Allocate a clone of the PriorityQueue. This can be used if you want to scan
 * through all elements of the PriorityQueue but you don't want to have to
 * remove the all and add them all again.
 *
 * @param pq the priority queue to clone
 * @return a clone of the original priority queue
 */
extern FrtPriorityQueue *frt_pq_clone(FrtPriorityQueue *pq);

/**
 * Clear all elements from the PriorityQueue and reset the size to 0. When
 * the elements are removed from the PriorityQueue, free_elem is used to free
 * them, unless it was set to NULL in which case nothing will happen to them.
 *
 * @param self the PriorityQueue to clear
 */
extern void frt_pq_clear(FrtPriorityQueue *self);

/**
 * Free the memory allocated to the PriorityQueue. This function does nothing
 * to the elements in the PriorityQueue itself. To destroy them also, use
 * pq_destroy.
 *
 * @param self the PriorityQueue to free
 */
extern void frt_pq_free(FrtPriorityQueue *self);

/**
 * Destroy the PriorityQueue, freeing all memory allocated to it and also
 * destroying all the elements contained by it. This method is equivalent to
 * calling pq_clear followed by pq_free.
 *
 * @param the PriorityQueue to destroy
 */
extern void frt_pq_destroy(FrtPriorityQueue *self);

/**
 * Reorder the PriorityQueue after the top element has been modified. This
 * method is used especially when the PriorityQueue contains a queue of
 * iterators. When the top iterator is incremented you should call this
 * method.
 *
 * @param self the PriorityQueue to reorder
 */
extern void frt_pq_down(FrtPriorityQueue *self);

/**
 * Add another element to the PriorityQueue. This method should only be used
 * when the PriorityQueue has enough space allocated to hold all elements
 * added. If there is a chance that you will add more than the amount you have
 * allocated then you should use pq_insert. pq_insert will handle insertion
 * overflow.
 *
 * @param self the PriorityQueue to add the element to
 * @param elem the element to add to the PriorityQueue
 */
extern void frt_pq_push(FrtPriorityQueue *self, void *elem);

typedef enum {
    FRT_PQ_DROPPED = 0,
    FRT_PQ_ADDED,
    FRT_PQ_INSERTED
} FrtPriorityQueueInsertEnum;

/**
 * Add another element to the PriorityQueue. Unlike pq_push, this method
 * handles insertion overflow. That is, when you insert more elements than the
 * capacity of the PriorityQueue, the elements are dropped off the bottom and
 * freed using the free_elem function.
 *
 * @param self the PriorityQueue to add the element to
 * @param elem the element to add to the PriorityQueue
 * @returns one of three values;
 *   <pre>
 *     0 == PQ_DROPPED  the element was too small (according to the less_than
 *                      function) so it was destroyed
 *     1 == PQ_ADDED    the element was successfully added
 *     2 == PQ_INSERTED the element was successfully added after another
 *                      element was dropped and destroyed
 *   </pre>
 */
extern FrtPriorityQueueInsertEnum frt_pq_insert(FrtPriorityQueue *self,
                                                   void *elem);

/**
 * Get the top element in the PriorityQueue.
 *
 * @param self the PriorityQueue to get the top from
 * @return the top element in the PriorityQueue
 */
extern void *frt_pq_top(FrtPriorityQueue *self);

/**
 * Remove and return the top element in the PriorityQueue.
 *
 * @param self the PriorityQueue to get the top from
 * @return the top element in the PriorityQueue
 */
extern void *frt_pq_pop(FrtPriorityQueue *self);

/**
 * Return true if the PriorityQueue is full.
 *
 * @param self the PriorityQueue to test
 * @return true if the PriorityQueue is full.
 */
#define frt_pq_full(pq) ((pq)->size == (pq)->capa)

#ifdef __cplusplus
} // extern "C"
#endif

#endif