Mstdlib-1.24.0
m_llist_bin.h
1/* The MIT License (MIT)
2 *
3 * Copyright (c) 2015 Monetra Technologies, LLC.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#ifndef __M_LLIST_BIN_H__
25#define __M_LLIST_BIN_H__
26
27/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28
29#include <mstdlib/base/m_defs.h>
30#include <mstdlib/base/m_types.h>
31
32/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
33
34__BEGIN_DECLS
35
36/*! \addtogroup m_llist_bin Linked List - Binary
37 * \ingroup m_llist
38 *
39 * Linked list for storing values.
40 *
41 * The list can be used in multiple ways:
42 * - Unsorted.
43 * - Sorted.
44 * - Queue (FIFO) (really just unsorted).
45 * - Priority Queue (really just sorted).
46 *
47 * A linked list is not indexable. Iteration and find are supported.
48 *
49 * Sorted notes:
50 * - Sorting is implemented as a skip list. This should provide near O(long(n)) performance.
51 * Performance nearing a sorted M_list_t.
52 * - Sorting is stable. If an element with a matching value is already in the list then it
53 * will be inserted after. Find will always find the first matching element in the list.
54 *
55 * @{
56 */
57
58struct M_llist_bin;
59/* Currently a direct map to M_list private opaque type,
60 * simply using casting to prevent the 'wrap' overhead of mallocing when it
61 * is not necessary */
62typedef struct M_llist_bin M_llist_bin_t;
63
64struct M_llist_bin_node;
65/* Currently a direct map to M_list private opaque type,
66 * simply using casting to prevent the 'wrap' overhead of mallocing when it
67 * is not necessary */
68typedef struct M_llist_bin_node M_llist_bin_node_t;
69
70
71/*! Flags for controlling the behavior of the list. */
72typedef enum {
73 M_LLIST_BIN_NONE = 0, /*!< List mode. */
74 M_LLIST_BIN_CIRCULAR = 1 << 0 /*!< Circular list. */
76
77
78/*! Type of matching that should be used when searching/modifying a value in the list. */
79typedef enum {
80 M_LLIST_BIN_MATCH_VAL = 0, /*!< Match based on the value. */
81 M_LLIST_BIN_MATCH_ALL = 1 << 0 /*!< Include all instances. */
83
84
85/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
86
87/*! Create a new list.
88 *
89 * A list is a linked list. The list can be, optionally, kept in sorted
90 * order. The sorted order is determined by the flags.
91 *
92 * \param[in] flags M_llist_bin_flags_t flags controlling behavior.
93 *
94 * \return Allocated linked list.
95 *
96 * \see M_llist_bin_destroy
97 */
98M_API M_llist_bin_t *M_llist_bin_create(M_uint32 flags) M_MALLOC;
99
100
101/*! Destroy the list.
102 *
103 * \param[in] d The llist to destory.
104 */
105M_API void M_llist_bin_destroy(M_llist_bin_t *d) M_FREE(1);
106
107
108/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
109
110/*! Insert a value into the list.
111 *
112 * If sorted the value will be inserted in sorted order. Otherwise it will be
113 * appended to the end of the list.
114 *
115 * \param[in,out] d The list.
116 * \param[in] val The value to insert.
117 * \param[in] len The length of val.
118 *
119 * \return Pointer to M_llist_bin_node_t container object of new node on success,
120 * otherwise NULL.
121 *
122 * \see m_llist_bin_insert_first
123 */
124M_API M_llist_bin_node_t *M_llist_bin_insert(M_llist_bin_t *d, const M_uint8 *val, size_t len);
125
126
127/*! Insert a value into the list as the first node.
128 *
129 * Only applies to unsorted lists.
130 *
131 * \param[in,out] d The list.
132 * \param[in] val The value to insert.
133 * \param[in] len The length of val.
134 *
135 * \return Pointer to M_llist_bin_node_t container object of new node on success,
136 * otherwise NULL.
137 *
138 * \see M_llist_bin_insert
139 */
140M_API M_llist_bin_node_t *M_llist_bin_insert_first(M_llist_bin_t *d, const M_uint8 *val, size_t len);
141
142
143/*! Insert a value into the list before a given node.
144 *
145 * Only applies to unsorted lists.
146 *
147 * \param[in,out] n The node to insert before. Cannot be NULL.
148 * \param[in] val The value to insert.
149 * \param[in] len The length of val.
150 *
151 * \return Pointer to M_llist_bin_node_t container object of new node on success,
152 * otherwise NULL.
153 *
154 * \see M_llist_bin_insert_after
155 */
156M_API M_llist_bin_node_t *M_llist_bin_insert_before(M_llist_bin_node_t *n, const M_uint8 *val, size_t len);
157
158
159/*! Insert a value into the list after a given node.
160 *
161 * Only applies to unsorted lists.
162 *
163 * \param[in,out] n The node to insert after. Cannot be NULL.
164 * \param[in] val The value to insert.
165 * \param[in] len The length of val.
166 *
167 * \return Pointer to M_llist_bin_node_t container object of new node on success,
168 * otherwise NULL.
169 *
170 * \see M_llist_bin_insert_before
171 */
172M_API M_llist_bin_node_t *M_llist_bin_insert_after(M_llist_bin_node_t *n, const M_uint8 *val, size_t len);
173
174
175/*! Set the node as the first node in the circular list.
176 *
177 * Only applies to circular lists.
178 *
179 * \param[in] n The node that should be considered first.
180 */
182
183
184/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
185
186/*! Move a node before another node in the list.
187 *
188 * \param[in] move The node to move.
189 * \param[in] before The node that move should be placed before.
190 *
191 * \return M_TRUE on sucess, otherwise M_FALSE.
192 */
194
195
196/*! Move a node after another node in the list.
197 *
198 * \param[in] move The node to move.
199 * \param[in] after The node that move should be placed after.
200 *
201 * \return M_TRUE on sucess, otherwise M_FALSE.
202 */
204
205
206/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
207
208/*! The length of the list.
209 *
210 * \param[in] d The list.
211 *
212 * \return the length of the list.
213 */
214M_API size_t M_llist_bin_len(const M_llist_bin_t *d);
215
216
217/*! Count the number of times a value occurs in the list.
218 *
219 * \param[in] d The list.
220 * \param[in] val The value to search for.
221 * \param[in] len The length of val.
222 *
223 *
224 * \return The number of times val appears in the list.
225 */
226M_API size_t M_llist_bin_count(const M_llist_bin_t *d, const M_uint8 *val, size_t len);
227
228
229/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
230
231/*! Get the first node in the list.
232 *
233 * \param[in] d The list.
234 *
235 * \return Node or NULL.
236 *
237 * \see M_llist_bin_last
238 * \see M_llist_bin_find
239 */
241
242
243/*! Get the last node in the list.
244 *
245 * \param[in] d The list.
246 *
247 * \return Node or NULL.
248 *
249 * \see M_llist_bin_first
250 * \see M_llist_bin_find
251 */
253
254
255/*! Find a node for the given value in the list.
256 *
257 * \param[in] d The list.
258 * \param[in] val The value to search for.
259 * \param[in] len The length of val.
260 *
261 *
262 * \return Node or NULL.
263 *
264 * \see M_llist_bin_first
265 * \see M_llist_bin_last
266 */
267M_API M_llist_bin_node_t *M_llist_bin_find(const M_llist_bin_t *d, const M_uint8 *val, size_t len);
268
269
270/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
271
272/*! Take the node from the list and return its value.
273 *
274 * The element will be removed from the list and its value returned. The caller is
275 * responsible for freeing the value.
276 *
277 * \param[in] n The node.
278 * \param[out] len The length of val.
279 *
280 * \return The node's value.
281 *
282 * \see M_llist_bin_node_val
283 */
284M_API M_uint8 *M_llist_bin_take_node(M_llist_bin_node_t *n, size_t *len);
285
286
287/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
288
289/*! Remove a node from the list.
290 *
291 * The value will be free'd using the value_free callback.
292 *
293 * \param[in] n The node.
294 *
295 * \return M_TRUE on success otherwise M_FALSE.
296 *
297 * \see M_llist_bin_remove_val
298 */
300
301
302/*! Remove node(s) from the list matching a given value.
303 *
304 * The value will be free'd using the value_free callback.
305 *
306 * \param[in,out] d The list.
307 * \param[in] val The value to search for.
308 * \param[in] len The length of val.
309 * \param[in] type M_llist_bin_match_type_t type of how the val should be matched.
310 * valid values are:
311 * - M_LLIST_BIN_MATCH_VAL (removes one/first)
312 * - M_LLIST_BIN_MATCH_ALL
313 *
314 * \return M_TRUE on success otherwise M_FALSE.
315 *
316 * \see M_llist_bin_remove_node
317 */
318M_API size_t M_llist_bin_remove_val(M_llist_bin_t *d, const M_uint8 *val, size_t len, M_uint32 type);
319
320
321/*! Remove duplicate values from the list.
322 *
323 * \param[in] d The list.
324 */
326
327
328/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
329
330/*! Get the next node, the one after a given node.
331 *
332 * \param[in] n The node.
333 *
334 * \return Node or NULL.
335 *
336 * \see M_llist_bin_node_prev
337 */
339
340
341/*! Get the previous node, the one before a given node.
342 *
343 * \param[in] n The node.
344 *
345 * \return Node or NULL.
346 *
347 * \see M_llist_bin_node_next
348 */
350
351
352/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
353
354/*! Get the value for a node.
355 *
356 * \param[in] n The node.
357 * \param[out] len The length of val.
358 *
359 *
360 * \return The node's value.
361 *
362 * \see M_llist_bin_take_node
363 */
364M_API const M_uint8 *M_llist_bin_node_val(const M_llist_bin_node_t *n, size_t *len);
365
366
367/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
368
369/*! Duplicate an existing list. Will copy all elements of the list.
370 *
371 * \param[in] d list to duplicate.
372 *
373 * \return New list.
374 */
376
377
378/*! Merge two lists together.
379 *
380 * The second (src) list will be destroyed automatically upon completion of this function. Any value pointers for the
381 * list will be directly copied over to the destination list, they will not be duplicated.
382 *
383 * \param[in,out] dest Pointer by reference to the list receiving the values.
384 * if this is NULL, the pointer will simply be switched out for src.
385 * \param[in,out] src Pointer to the list giving up its values.
386 * \param[in] include_duplicates When M_TRUE any values in 'dest' that also exist in
387 * 'src' will be included in 'dest'. When M_FALSE any
388 * duplicate values will not be added to 'dest'.
389 */
390M_API void M_llist_bin_merge(M_llist_bin_t **dest, M_llist_bin_t *src, M_bool include_duplicates) M_FREE(2);
391
392/*! @} */
393
394__END_DECLS
395
396#endif /* __M_LLIST_BIN_H__ */
M_llist_bin_node_t * M_llist_bin_node_next(const M_llist_bin_node_t *n)
void M_llist_bin_destroy(M_llist_bin_t *d) M_FREE(1)
M_llist_bin_node_t * M_llist_bin_insert_before(M_llist_bin_node_t *n, const M_uint8 *val, size_t len)
M_uint8 * M_llist_bin_take_node(M_llist_bin_node_t *n, size_t *len)
const M_uint8 * M_llist_bin_node_val(const M_llist_bin_node_t *n, size_t *len)
size_t M_llist_bin_remove_val(M_llist_bin_t *d, const M_uint8 *val, size_t len, M_uint32 type)
M_llist_bin_node_t * M_llist_bin_insert_after(M_llist_bin_node_t *n, const M_uint8 *val, size_t len)
M_llist_bin_node_t * M_llist_bin_first(const M_llist_bin_t *d)
void M_llist_bin_remove_duplicates(M_llist_bin_t *d)
size_t M_llist_bin_count(const M_llist_bin_t *d, const M_uint8 *val, size_t len)
M_llist_bin_node_t * M_llist_bin_last(const M_llist_bin_t *d)
size_t M_llist_bin_len(const M_llist_bin_t *d)
void M_llist_bin_merge(M_llist_bin_t **dest, M_llist_bin_t *src, M_bool include_duplicates) M_FREE(2)
struct M_llist_bin M_llist_bin_t
Definition: m_llist_bin.h:62
M_llist_bin_t * M_llist_bin_create(M_uint32 flags) M_MALLOC
M_llist_bin_flags_t
Definition: m_llist_bin.h:72
M_bool M_llist_bin_remove_node(M_llist_bin_node_t *n)
void M_llist_bin_set_first(M_llist_bin_node_t *n)
M_llist_bin_t * M_llist_bin_duplicate(const M_llist_bin_t *d) M_MALLOC
M_bool M_llist_bin_move_after(M_llist_bin_node_t *move, M_llist_bin_node_t *after)
M_llist_bin_node_t * M_llist_bin_find(const M_llist_bin_t *d, const M_uint8 *val, size_t len)
M_llist_bin_node_t * M_llist_bin_node_prev(const M_llist_bin_node_t *n)
M_llist_bin_node_t * M_llist_bin_insert(M_llist_bin_t *d, const M_uint8 *val, size_t len)
struct M_llist_bin_node M_llist_bin_node_t
Definition: m_llist_bin.h:68
M_llist_bin_match_type_t
Definition: m_llist_bin.h:79
M_llist_bin_node_t * M_llist_bin_insert_first(M_llist_bin_t *d, const M_uint8 *val, size_t len)
M_bool M_llist_bin_move_before(M_llist_bin_node_t *move, M_llist_bin_node_t *before)
@ M_LLIST_BIN_NONE
Definition: m_llist_bin.h:73
@ M_LLIST_BIN_CIRCULAR
Definition: m_llist_bin.h:74
@ M_LLIST_BIN_MATCH_VAL
Definition: m_llist_bin.h:80
@ M_LLIST_BIN_MATCH_ALL
Definition: m_llist_bin.h:81