Add Doxygen documentation for API changes from 1.6.0 to 1.6.1
[asterisk/asterisk.git] / include / asterisk / heap.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2009, Digium, Inc.
5  *
6  * Russell Bryant <russell@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file
21  * \brief Max Heap data structure
22  * \author Russell Bryant <russell@digium.com>
23  */
24
25 #ifndef __AST_HEAP_H__
26 #define __AST_HEAP_H__
27
28 /*!
29  * \brief A max heap.
30  *
31  * \note Thread-safety is left to the user of the API.  The heap API provides
32  *       no locking of its own.  If the heap will be accessed by multiple threads,
33  *       then a lock must be used to ensure that only a single operation is
34  *       done on the heap at a time.  For the sake of convenience, a lock is
35  *       provided for the user of the API to use if another lock is not already
36  *       available to protect the heap.
37  */
38 struct ast_heap;
39
40 /*!
41  * \brief Function type for comparing nodes in a heap
42  *
43  * \param elm1 the first element
44  * \param elm2 the second element
45  *
46  * \retval negative if elm1 < elm2
47  * \retval 0 if elm1 == elm2
48  * \retval positive if elm1 > elm2
49  *
50  * \note This implementation is of a max heap.  However, if a min heap is
51  *       desired, simply swap the return values of this function.
52  *
53  * \since 1.6.1
54  */
55 typedef int (*ast_heap_cmp_fn)(void *elm1, void *elm2);
56
57 /*!
58  * \brief Create a max heap
59  *
60  * \param init_height The initial height of the heap to allocate space for.
61  *        To start out, there will be room for (2 ^ init_height) - 1 entries.
62  *        However, the heap will grow as needed.
63  * \param cmp_fn The function that should be used to compare elements in the heap.
64  * \param index_offset This parameter is optional, but must be provided to be able
65  *        to use ast_heap_remove().  This is the number of bytes into the element
66  *        where an ssize_t has been made available for the heap's internal
67  *        use.  The heap will use this field to keep track of the element's current
68  *        position in the heap.  The offsetof() macro is useful for providing a
69  *        proper value for this argument.  If ast_heap_remove() will not be used,
70  *        then a negative value can be provided to indicate that no field for an
71  *        offset has been allocated.
72  *
73  * Example Usage:
74  *
75  * \code
76  *
77  * struct myobj {
78  *    int foo;
79  *    int bar;
80  *    char stuff[8];
81  *    char things[8];
82  *    ssize_t __heap_index;
83  * };
84  *
85  * ...
86  *
87  * static int myobj_cmp(void *obj1, void *obj2);
88  *
89  * ...
90  *
91  * struct ast_heap *h;
92  *
93  * h = ast_heap_create(8, myobj_cmp, offsetof(struct myobj, __heap_index));
94  *
95  * \endcode
96  *
97  * \return An instance of a max heap
98  * \since 1.6.1
99  */
100 struct ast_heap *ast_heap_create(unsigned int init_height, ast_heap_cmp_fn cmp_fn,
101                 ssize_t index_offset);
102
103 /*!
104  * \brief Destroy a max heap
105  *
106  * \param h the heap to destroy
107  *
108  * \return NULL for convenience
109  * \since 1.6.1
110  */
111 struct ast_heap *ast_heap_destroy(struct ast_heap *h);
112
113 /*!
114  * \brief Push an element on to a heap
115  *
116  * \param h the heap being added to
117  * \param elm the element being put on the heap
118  *
119  * \retval 0 success
120  * \retval non-zero failure
121  * \since 1.6.1
122  */
123 int ast_heap_push(struct ast_heap *h, void *elm);
124
125 /*!
126  * \brief Pop the max element off of the heap
127  *
128  * \param h the heap
129  *
130  * \return this will return the element on the top of the heap, which has the
131  *         largest value according to the element comparison function that was
132  *         provided when the heap was created.  The element will be removed before
133  *         being returned.
134  * \since 1.6.1
135  */
136 void *ast_heap_pop(struct ast_heap *h);
137
138 /*!
139  * \brief Remove a specific element from a heap
140  *
141  * \param h the heap to remove from
142  * \param elm the element to remove
143  *
144  * \return elm, if the removal was successful, or NULL if it failed
145  *
146  * \note the index_offset parameter to ast_heap_create() is required to be able
147  *       to use this function.
148  * \since 1.6.1
149  */
150 void *ast_heap_remove(struct ast_heap *h, void *elm);
151
152 /*!
153  * \brief Peek at an element on a heap
154  *
155  * \param h the heap
156  * \param index index of the element to return.  The first element is at index 1,
157  *        and the last element is at the index == the size of the heap.
158  *
159  * \return an element at the specified index on the heap.  This element will \b not
160  *         be removed before being returned.
161  *
162  * \note If this function is being used in combination with ast_heap_size() for
163  *       purposes of traversing the heap, the heap must be locked for the entire
164  *       duration of the traversal.
165  *
166  * Example code for a traversal:
167  * \code
168  *
169  * struct ast_heap *h;
170  *
171  * ...
172  *
173  * size_t size, i;
174  * void *cur_obj;
175  *
176  * ast_heap_rdlock(h);
177  *
178  * size = ast_heap_size(h);
179  *
180  * for (i = 1; i <= size && (cur_obj = ast_heap_peek(h, i)); i++) {
181  *     ... Do stuff with cur_obj ...
182  * }
183  *
184  * ast_heap_unlock(h);
185  *
186  * \endcode
187  * \since 1.6.1
188  */
189 void *ast_heap_peek(struct ast_heap *h, unsigned int index);
190
191 /*!
192  * \brief Get the current size of a heap
193  *
194  * \param h the heap
195  *
196  * \return the number of elements currently in the heap
197  * \since 1.6.1
198  */
199 size_t ast_heap_size(struct ast_heap *h);
200
201 /*!
202  * \brief Write-Lock a heap
203  *
204  * \param h the heap
205  *
206  * A lock is provided for convenience.  It can be assumed that none of the
207  * ast_heap API calls are thread safe.  This lock does not have to be used
208  * if another one is already available to protect the heap.
209  *
210  * \return see the documentation for pthread_rwlock_wrlock()
211  * \since 1.6.1
212  */
213 int ast_heap_wrlock(struct ast_heap *h);
214
215 /*!
216  * \brief Read-Lock a heap
217  *
218  * \param h the heap
219  *
220  * A lock is provided for convenience.  It can be assumed that none of the
221  * ast_heap API calls are thread safe.  This lock does not have to be used
222  * if another one is already available to protect the heap.
223  *
224  * \return see the documentation for pthread_rwlock_rdlock()
225  * \since 1.6.1
226  */
227 int ast_heap_rdlock(struct ast_heap *h);
228
229 /*!
230  * \brief Unlock a heap
231  *
232  * \param h the heap
233  *
234  * \return see the documentation for pthread_rwlock_unlock()
235  * \since 1.6.1
236  */
237 int ast_heap_unlock(struct ast_heap *h);
238
239 /*!
240  * \brief Verify that a heap has been properly constructed
241  *
242  * \param h a heap
243  *
244  * \retval 0 success
245  * \retval non-zero failure
246  *
247  * \note This function is mostly for debugging purposes.  It traverses an existing
248  *       heap and verifies that every node is properly placed relative to its children.
249  * \since 1.6.1
250  */
251 int ast_heap_verify(struct ast_heap *h);
252
253 #endif /* __AST_HEAP_H__ */