]> git.proxmox.com Git - mirror_frr.git/blob - doc/developer/lists.rst
Merge pull request #4297 from vishaldhingra/rmap
[mirror_frr.git] / doc / developer / lists.rst
1 List implementations
2 ====================
3
4 .. note::
5
6 The term *list* is used generically for lists, skiplists, trees and hash
7 tables in this document.
8
9 Common list interface
10 ---------------------
11
12 FRR includes a set of list-like data structure implementations with abstracted
13 common APIs. The purpose of this is easily allow swapping out one
14 data structure for another while also making the code easier to read and write.
15 There is one API for unsorted lists and a similar but not identical API for
16 sorted lists.
17
18 For unsorted lists, the following implementations exist:
19
20 - single-linked list with tail pointer (e.g. STAILQ in BSD)
21
22 - atomic single-linked list with tail pointer
23
24
25 For sorted lists, these data structures are implemented:
26
27 - single-linked list
28
29 - atomic single-linked list
30
31 - skiplist
32
33 - red-black tree (based on OpenBSD RB_TREE)
34
35 - hash table (note below)
36
37 Except for hash tables, each of the sorted data structures has a variant with
38 unique and non-unique list items. Hash tables always require unique items
39 and mostly follow the "sorted" API but use the hash value as sorting
40 key. Also, iterating while modifying does not work with hash tables.
41
42
43 The following sorted structures are likely to be implemented at some point
44 in the future:
45
46 - atomic skiplist
47
48 - atomic hash table (note below)
49
50
51 The APIs are all designed to be as type-safe as possible. This means that
52 there will be a compiler warning when an item doesn't match the list, or
53 the return value has a different type, or other similar situations. **You
54 should never use casts with these APIs.** If a cast is neccessary in relation
55 to these APIs, there is probably something wrong with the overall design.
56
57 Only the following pieces use dynamically allocated memory:
58
59 - the hash table itself is dynamically grown and shrunk
60
61 - skiplists store up to 4 next pointers inline but will dynamically allocate
62 memory to hold an item's 5th up to 16th next pointer (if they exist)
63
64 Cheat sheet
65 -----------
66
67 Available types:
68
69 ::
70
71 DECLARE_LIST
72 DECLARE_ATOMLIST
73
74 DECLARE_SORTLIST_UNIQ
75 DECLARE_SORTLIST_NONUNIQ
76 DECLARE_ATOMLIST_UNIQ
77 DECLARE_ATOMLIST_NONUNIQ
78 DECLARE_SKIPLIST_UNIQ
79 DECLARE_SKIPLIST_NONUNIQ
80 DECLARE_RBTREE_UNIQ
81 DECLARE_RBTREE_NONUNIQ
82
83 DECLARE_HASH
84
85 Functions provided:
86
87 +------------------------------------+------+------+---------+------------+
88 | Function | LIST | HASH | \*_UNIQ | \*_NONUNIQ |
89 +====================================+======+======+=========+============+
90 | _init, _fini | yes | yes | yes | yes |
91 +------------------------------------+------+------+---------+------------+
92 | _first, _next, _next_safe | yes | yes | yes | yes |
93 +------------------------------------+------+------+---------+------------+
94 | _add_head, _add_tail, _add_after | yes | -- | -- | -- |
95 +------------------------------------+------+------+---------+------------+
96 | _add | -- | yes | yes | yes |
97 +------------------------------------+------+------+---------+------------+
98 | _del, _pop | yes | yes | yes | yes |
99 +------------------------------------+------+------+---------+------------+
100 | _find | -- | yes | yes | -- |
101 +------------------------------------+------+------+---------+------------+
102 | _find_lt, _find_gteq | -- | -- | yes | yes |
103 +------------------------------------+------+------+---------+------------+
104 | use with for_each() macros | yes | yes | yes | yes |
105 +------------------------------------+------+------+---------+------------+
106
107
108 Datastructure type setup
109 ------------------------
110
111 Each of the data structures has a ``PREDECL_*`` and a ``DECLARE_*`` macro to
112 set up an "instantiation" of the list. This works somewhat similar to C++
113 templating, though much simpler.
114
115 **In all following text, the Z prefix is replaced with a name choosen
116 for the instance of the datastructure.**
117
118 The common setup pattern will look like this:
119
120 .. code-block:: c
121
122 #include <typesafe.h>
123
124 PREDECL_XXX(Z)
125 struct item {
126 int otherdata;
127 struct Z_item mylistitem;
128 }
129
130 struct Z_head mylisthead;
131
132 /* unsorted: */
133 DECLARE_XXX(Z, struct item, mylistitem)
134
135 /* sorted, items that compare as equal cannot be added to list */
136 int compare_func(const struct item *a, const struct item *b);
137 DECLARE_XXX_UNIQ(Z, struct item, mylistitem, compare_func)
138
139 /* sorted, items that compare as equal can be added to list */
140 int compare_func(const struct item *a, const struct item *b);
141 DECLARE_XXX_NONUNIQ(Z, struct item, mylistitem, compare_func)
142
143 /* hash tables: */
144 int compare_func(const struct item *a, const struct item *b);
145 uint32_t hash_func(const struct item *a);
146 DECLARE_XXX(Z, struct item, mylistitem, compare_func, hash_func)
147
148 ``XXX`` is replaced with the name of the data structure, e.g. ``SKIPLIST``
149 or ``ATOMLIST``. The ``DECLARE_XXX`` invocation can either occur in a `.h`
150 file (if the list needs to be accessed from several C files) or it can be
151 placed in a `.c` file (if the list is only accessed from that file.) The
152 ``PREDECL_XXX`` invocation defines the ``struct Z_item`` and ``struct
153 Z_head`` types and must therefore occur before these are used.
154
155 To switch between compatible data structures, only these two lines need to be
156 changes. To switch to a data structure with a different API, some source
157 changes are necessary.
158
159 Common iteration macros
160 -----------------------
161
162 The following iteration macros work across all data structures:
163
164 .. c:function:: for_each(Z, &head, item)
165
166 Equivalent to:
167
168 .. code-block:: c
169
170 for (item = Z_first(&head); item; item = Z_next(&head, item))
171
172 Note that this will fail if the list is modified while being iterated
173 over.
174
175 .. c:function:: for_each_safe(Z, &head, item)
176
177 Same as the previous, but the next element is pre-loaded into a "hidden"
178 variable (named ``Z_safe``.) Equivalent to:
179
180 .. code-block:: c
181
182 for (item = Z_first(&head); item; item = next) {
183 next = Z_next_safe(&head, item);
184 ...
185 }
186
187 .. warning::
188
189 Iterating over hash tables while adding or removing items is not
190 possible. The iteration position will be corrupted when the hash
191 tables is resized while iterating. This will cause items to be
192 skipped or iterated over twice.
193
194 .. c:function:: for_each_from(Z, &head, item, from)
195
196 Iterates over the list, starting at item ``from``. This variant is "safe"
197 as in the previous macro. Equivalent to:
198
199 .. code-block:: c
200
201 for (item = from; item; item = from) {
202 from = Z_next_safe(&head, item);
203 ...
204 }
205
206 .. note::
207
208 The ``from`` variable is written to. This is intentional - you can
209 resume iteration after breaking out of the loop by keeping the ``from``
210 value persistent and reusing it for the next loop.
211
212 Common API
213 ----------
214
215 The following documentation assumes that a list has been defined using
216 ``Z`` as the name, and ``itemtype`` being the type of the list items (e.g.
217 ``struct item``.)
218
219 .. c:function:: void Z_init(struct Z_head *)
220
221 Initializes the list for use. For most implementations, this just sets
222 some values. Hash tables are the only implementation that allocates
223 memory in this call.
224
225 .. c:function:: void Z_fini(struct Z_head *)
226
227 Reverse the effects of :c:func:`Z_init()`. The list must be empty
228 when this function is called.
229
230 .. warning::
231
232 This function may ``assert()`` if the list is not empty.
233
234 .. c:function:: size_t Z_count(struct Z_head *)
235
236 Returns the number of items in a structure. All structures store a
237 counter in their `Z_head` so that calling this function completes
238 in O(1).
239
240 .. note::
241
242 For atomic lists with concurrent access, the value will already be
243 outdated by the time this function returns and can therefore only be
244 used as an estimate.
245
246 .. c:function:: itemtype *Z_first(struct Z_head *)
247
248 Returns the first item in the structure, or ``NULL`` if the structure is
249 empty. This is O(1) for all data structures except red-black trees
250 where it is O(log n).
251
252 .. c:function:: itemtype *Z_pop(struct Z_head *)
253
254 Remove and return the first item in the structure, or ``NULL`` if the
255 structure is empty. Like :c:func:`Z_first`, this is O(1) for all
256 data structures except red-black trees where it is O(log n) again.
257
258 This function can be used to build queues (with unsorted structures) or
259 priority queues (with sorted structures.)
260
261 Another common pattern is deleting all list items:
262
263 .. code-block:: c
264
265 while ((item = Z_pop(head)))
266 item_free(item);
267
268 .. note::
269
270 This function can - and should - be used with hash tables. It is not
271 affected by the "modification while iterating" problem. To remove
272 all items from a hash table, use the loop demonstrated above.
273
274 .. c:function:: itemtype *Z_next(struct Z_head *, itemtype *prev)
275
276 Return the item that follows after ``prev``, or ``NULL`` if ``prev`` is
277 the last item.
278
279 .. warning::
280
281 ``prev`` must not be ``NULL``! Use :c:func:`Z_next_safe()` if
282 ``prev`` might be ``NULL``.
283
284 .. c:function:: itemtype *Z_next_safe(struct Z_head *, itemtype *prev)
285
286 Same as :c:func:`Z_next()`, except that ``NULL`` is returned if
287 ``prev`` is ``NULL``.
288
289 .. c:function:: itemtype *Z_del(struct Z_head *, itemtype *item)
290
291 Remove ``item`` from the list and return it.
292
293 .. note::
294
295 This function's behaviour is undefined if ``item`` is not actually
296 on the list. Some structures return ``NULL`` in this case while others
297 return ``item``. The function may also call ``assert()`` (but most
298 don't.)
299
300 .. todo::
301
302 ``Z_del_after()`` / ``Z_del_hint()``?
303
304 API for unsorted structures
305 ---------------------------
306
307 Since the insertion position is not pre-defined for unsorted data, there
308 are several functions exposed to insert data:
309
310 .. note::
311
312 ``item`` must not be ``NULL`` for any of the following functions.
313
314 .. c:function:: DECLARE_XXX(Z, type, field)
315
316 :param listtype XXX: ``LIST`` or ``ATOMLIST`` to select a data structure
317 implementation.
318 :param token Z: Gives the name prefix that is used for the functions
319 created for this instantiation. ``DECLARE_XXX(foo, ...)``
320 gives ``struct foo_item``, ``foo_add_head()``, ``foo_count()``, etc. Note
321 that this must match the value given in ``PREDECL_XXX(foo)``.
322 :param typename type: Specifies the data type of the list items, e.g.
323 ``struct item``. Note that ``struct`` must be added here, it is not
324 automatically added.
325 :param token field: References a struct member of ``type`` that must be
326 typed as ``struct foo_item``. This struct member is used to
327 store "next" pointers or other data structure specific data.
328
329 .. c:function:: void Z_add_head(struct Z_head *, itemtype *item)
330
331 Insert an item at the beginning of the structure, before the first item.
332 This is an O(1) operation for non-atomic lists.
333
334 .. c:function:: void Z_add_tail(struct Z_head *, itemtype *item)
335
336 Insert an item at the end of the structure, after the last item.
337 This is also an O(1) operation for non-atomic lists.
338
339 .. c:function:: void Z_add_after(struct Z_head *, itemtype *after, itemtype *item)
340
341 Insert ``item`` behind ``after``. If ``after`` is ``NULL``, the item is
342 inserted at the beginning of the list as with :c:func:`Z_add_head`.
343 This is also an O(1) operation for non-atomic lists.
344
345 A common pattern is to keep a "previous" pointer around while iterating:
346
347 .. code-block:: c
348
349 itemtype *prev = NULL, *item;
350
351 for_each_safe(Z, head, item) {
352 if (something) {
353 Z_add_after(head, prev, item);
354 break;
355 }
356 prev = item;
357 }
358
359 .. todo::
360
361 maybe flip the order of ``item`` & ``after``?
362 ``Z_add_after(head, item, after)``
363
364 API for sorted structures
365 -------------------------
366
367 Sorted data structures do not need to have an insertion position specified,
368 therefore the insertion calls are different from unsorted lists. Also,
369 sorted lists can be searched for a value.
370
371 .. c:function:: DECLARE_XXX_UNIQ(Z, type, field, compare_func)
372
373 :param listtype XXX: One of the following:
374 ``SORTLIST`` (single-linked sorted list), ``SKIPLIST`` (skiplist),
375 ``RBTREE`` (RB-tree) or ``ATOMSORT`` (atomic single-linked list).
376 :param token Z: Gives the name prefix that is used for the functions
377 created for this instantiation. ``DECLARE_XXX(foo, ...)``
378 gives ``struct foo_item``, ``foo_add()``, ``foo_count()``, etc. Note
379 that this must match the value given in ``PREDECL_XXX(foo)``.
380 :param typename type: Specifies the data type of the list items, e.g.
381 ``struct item``. Note that ``struct`` must be added here, it is not
382 automatically added.
383 :param token field: References a struct member of ``type`` that must be
384 typed as ``struct foo_item``. This struct member is used to
385 store "next" pointers or other data structure specific data.
386 :param funcptr compare_func: Item comparison function, must have the
387 following function signature:
388 ``int function(const itemtype *, const itemtype*)``. This function
389 may be static if the list is only used in one file.
390
391 .. c:function:: DECLARE_XXX_NONUNIQ(Z, type, field, compare_func)
392
393 Same as above, but allow adding multiple items to the list that compare
394 as equal in ``compare_func``. Ordering between these items is undefined
395 and depends on the list implementation.
396
397 .. c:function:: itemtype *Z_add(struct Z_head *, itemtype *item)
398
399 Insert an item at the appropriate sorted position. If another item exists
400 in the list that compares as equal (``compare_func()`` == 0), ``item`` is
401 not inserted into the list and the already-existing item in the list is
402 returned. Otherwise, on successful insertion, ``NULL`` is returned.
403
404 For ``_NONUNIQ`` lists, this function always returns NULL since ``item``
405 can always be successfully added to the list.
406
407 .. c:function:: itemtype *Z_find(struct Z_head *, const itemtype *ref)
408
409 Search the list for an item that compares equal to ``ref``. If no equal
410 item is found, return ``NULL``.
411
412 This function is likely used with a temporary stack-allocated value for
413 ``ref`` like so:
414
415 .. code-block:: c
416
417 itemtype searchfor = { .foo = 123 };
418
419 itemtype *item = Z_find(head, &searchfor);
420
421 .. note::
422
423 The ``Z_find()`` function is only available for lists that contain
424 unique items (i.e. ``DECLARE_XXX_UNIQ``.) This is because on a list
425 containing non-unique items, more than one item may compare as equal to
426 the item that is searched for.
427
428 .. c:function:: itemtype *Z_find_gteq(struct Z_head *, const itemtype *ref)
429
430 Search the list for an item that compares greater or equal to
431 ``ref``. See :c:func:`Z_find()` above.
432
433 .. c:function:: itemtype *Z_find_lt(struct Z_head *, const itemtype *ref)
434
435 Search the list for an item that compares less than
436 ``ref``. See :c:func:`Z_find()` above.
437
438
439 API for hash tables
440 -------------------
441
442 .. c:function:: DECLARE_XXX(Z, type, field, compare_func, hash_func)
443
444 :param listtype XXX: Only ``HASH`` is currently available.
445 :param token Z: Gives the name prefix that is used for the functions
446 created for this instantiation. ``DECLARE_XXX(foo, ...)``
447 gives ``struct foo_item``, ``foo_add()``, ``foo_count()``, etc. Note
448 that this must match the value given in ``PREDECL_XXX(foo)``.
449 :param typename type: Specifies the data type of the list items, e.g.
450 ``struct item``. Note that ``struct`` must be added here, it is not
451 automatically added.
452 :param token field: References a struct member of ``type`` that must be
453 typed as ``struct foo_item``. This struct member is used to
454 store "next" pointers or other data structure specific data.
455 :param funcptr compare_func: Item comparison function, must have the
456 following function signature:
457 ``int function(const itemtype *, const itemtype*)``. This function
458 may be static if the list is only used in one file. For hash tables,
459 this function is only used to check for equality, the ordering is
460 ignored.
461 :param funcptr hash_func: Hash calculation function, must have the
462 following function signature:
463 ``uint32_t function(const itemtype *)``. The hash value for items
464 stored in a hash table is cached in each item, so this value need not
465 be cached by the user code.
466
467 .. warning::
468
469 Items that compare as equal cannot be inserted. Refer to the notes
470 about sorted structures in the previous section.
471
472 .. c:function:: void Z_init_size(struct Z_head *, size_t size)
473
474 Same as :c:func:`Z_init()` but preset the minimum hash table to
475 ``size``.
476
477 Hash tables also support :c:func:`Z_add()` and :c:func:`Z_find()` with
478 the same semantics as noted above. :c:func:`Z_find_gteq()` and
479 :c:func:`Z_find_lt()` are **not** provided for hash tables.
480
481
482 Atomic lists
483 ------------
484
485 `atomlist.h` provides an unsorted and a sorted atomic single-linked list.
486 Since atomic memory accesses can be considerably slower than plain memory
487 accessses (depending on the CPU type), these lists should only be used where
488 neccessary.
489
490 The following guarantees are provided regarding concurrent access:
491
492 - the operations are lock-free but not wait-free.
493
494 Lock-free means that it is impossible for all threads to be blocked. Some
495 thread will always make progress, regardless of what other threads do. (This
496 even includes a random thread being stopped by a debugger in a random
497 location.)
498
499 Wait-free implies that the time any single thread might spend in one of the
500 calls is bounded. This is not provided here since it is not normally
501 relevant to practical operations. What this means is that if some thread is
502 hammering a particular list with requests, it is possible that another
503 thread is blocked for an extended time. The lock-free guarantee still
504 applies since the hammering thread is making progress.
505
506 - without a RCU mechanism in place, the point of contention for atomic lists
507 is memory deallocation. As it is, **a rwlock is required for correct
508 operation**. The *read* lock must be held for all accesses, including
509 reading the list, adding items to the list, and removing items from the
510 list. The *write* lock must be acquired and released before deallocating
511 any list element. If this is not followed, an use-after-free can occur
512 as a MT race condition when an element gets deallocated while another
513 thread is accessing the list.
514
515 .. note::
516
517 The *write* lock does not need to be held for deleting items from the
518 list, and there should not be any instructions between the
519 ``pthread_rwlock_wrlock`` and ``pthread_rwlock_unlock``. The write lock
520 is used as a sequence point, not as an exclusion mechanism.
521
522 - insertion operations are always safe to do with the read lock held.
523 Added items are immediately visible after the insertion call returns and
524 should not be touched anymore.
525
526 - when removing a *particular* (pre-determined) item, the caller must ensure
527 that no other thread is attempting to remove that same item. If this cannot
528 be guaranteed by architecture, a separate lock might need to be added.
529
530 - concurrent `pop` calls are always safe to do with only the read lock held.
531 This does not fall under the previous rule since the `pop` call will select
532 the next item if the first is already being removed by another thread.
533
534 **Deallocation locking still applies.** Assume another thread starts
535 reading the list, but gets task-switched by the kernel while reading the
536 first item. `pop` will happily remove and return that item. If it is
537 deallocated without acquiring and releasing the write lock, the other thread
538 will later resume execution and try to access the now-deleted element.
539
540 - the list count should be considered an estimate. Since there might be
541 concurrent insertions or removals in progress, it might already be outdated
542 by the time the call returns. No attempt is made to have it be correct even
543 for a nanosecond.
544
545 Overall, atomic lists are well-suited for MT queues; concurrent insertion,
546 iteration and removal operations will work with the read lock held.
547
548 Code snippets
549 ^^^^^^^^^^^^^
550
551 Iteration:
552
553 .. code-block:: c
554
555 struct item *i;
556
557 pthread_rwlock_rdlock(&itemhead_rwlock);
558 for_each(itemlist, &itemhead, i) {
559 /* lock must remain held while iterating */
560 ...
561 }
562 pthread_rwlock_unlock(&itemhead_rwlock);
563
564 Head removal (pop) and deallocation:
565
566 .. code-block:: c
567
568 struct item *i;
569
570 pthread_rwlock_rdlock(&itemhead_rwlock);
571 i = itemlist_pop(&itemhead);
572 pthread_rwlock_unlock(&itemhead_rwlock);
573
574 /* i might still be visible for another thread doing an
575 * for_each() (but won't be returned by another pop()) */
576 ...
577
578 pthread_rwlock_wrlock(&itemhead_rwlock);
579 pthread_rwlock_unlock(&itemhead_rwlock);
580 /* i now guaranteed to be gone from the list.
581 * note nothing between wrlock() and unlock() */
582 XFREE(MTYPE_ITEM, i);
583
584 FRR lists
585 ---------
586
587 .. TODO::
588
589 document
590
591 BSD lists
592 ---------
593
594 .. TODO::
595
596 refer to external docs