|
|
@node Container data types |
|
|
@section Container data types |
|
|
|
|
|
@c Copyright (C) 2019--2025 Free Software Foundation, Inc. |
|
|
|
|
|
@c Permission is granted to copy, distribute and/or modify this document |
|
|
@c under the terms of the GNU Free Documentation License, Version 1.3 or |
|
|
@c any later version published by the Free Software Foundation |
|
|
@c Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A |
|
|
@c copy of the license is at <https://www.gnu.org/licenses/fdl-1.3.en.html>. |
|
|
|
|
|
@c Written by Bruno Haible. |
|
|
|
|
|
@c This macro expands to \log in TeX mode, but just 'log' in HTML and info |
|
|
@c modes. |
|
|
@ifnottex |
|
|
@macro log |
|
|
log |
|
|
@end macro |
|
|
@end ifnottex |
|
|
|
|
|
@c This macro expands to \mathopsup in TeX mode, to a superscript in HTML |
|
|
@c mode, and to ^ without braces in info mode. |
|
|
@ifhtml |
|
|
@macro mathopsup {EXP} |
|
|
@sup{\EXP\} |
|
|
@end macro |
|
|
@end ifhtml |
|
|
@ifinfo |
|
|
@macro mathopsup {EXP} |
|
|
^\EXP\ |
|
|
@end macro |
|
|
@end ifinfo |
|
|
|
|
|
Gnulib provides several generic container data types. They can be used |
|
|
to organize collections of application-defined objects. |
|
|
|
|
|
@node Ordinary containers |
|
|
@subsection Ordinary container data types |
|
|
|
|
|
@mindex list |
|
|
@mindex set |
|
|
@mindex oset |
|
|
@mindex map |
|
|
@mindex omap |
|
|
|
|
|
@ifinfo |
|
|
@multitable @columnfractions .15 .45 .09 .15 .16 |
|
|
@end ifinfo |
|
|
@ifnotinfo |
|
|
@multitable @columnfractions .15 .5 .1 .1 .15 |
|
|
@end ifnotinfo |
|
|
@headitem Data type |
|
|
@tab Details |
|
|
@tab Module |
|
|
@tab Main include file |
|
|
@tab Include file for operations with out-of-memory checking |
|
|
@item Sequential list |
|
|
@tab Can contain any number of objects in any given order. |
|
|
Duplicates are allowed, but can optionally be forbidden. |
|
|
@tab @code{list} |
|
|
@tab @code{"gl_list.h"} |
|
|
@tab @code{"gl_xlist.h"} |
|
|
@item Set |
|
|
@tab Can contain any number of objects |
|
|
Duplicates (in the sense of the comparator) are forbidden. |
|
|
@tab @code{set} |
|
|
@tab @code{"gl_set.h"} |
|
|
@tab @code{"gl_xset.h"} |
|
|
@item Ordered set |
|
|
@tab Can contain any number of objects in the order of a given comparator |
|
|
function. |
|
|
Duplicates (in the sense of the comparator) are forbidden. |
|
|
@tab @code{oset} |
|
|
@tab @code{"gl_oset.h"} |
|
|
@tab @code{"gl_xoset.h"} |
|
|
@item Map |
|
|
@tab Can contain any number of (key, value) pairs, where keys and values |
|
|
are objects |
|
|
there are no (key, value1) and (key, value2) pairs with the same key |
|
|
(in the sense of a given comparator function). |
|
|
@tab @code{map} |
|
|
@tab @code{"gl_map.h"} |
|
|
@tab @code{"gl_xmap.h"} |
|
|
@item Ordered map |
|
|
@tab Can contain any number of (key, value) pairs, where keys and values |
|
|
are objects |
|
|
the (key, value) pairs are ordered by the key, in the order of a given |
|
|
comparator function |
|
|
there are no (key, value1) and (key, value2) pairs with the same key |
|
|
(in the sense of the comparator function). |
|
|
@tab @code{omap} |
|
|
@tab @code{"gl_omap.h"} |
|
|
@tab @code{"gl_xomap.h"} |
|
|
@end multitable |
|
|
|
|
|
Operations without out-of-memory checking (suitable for use in libraries) are |
|
|
declared in the ``main include file''. Whereas operations with out-of-memory |
|
|
checking (suitable only in programs) are declared in the ``include file for |
|
|
operations with out-of-memory checking''. |
|
|
|
|
|
For each of the data types, several implementations are available, with |
|
|
different performance profiles with respect to the available operations. |
|
|
This enables you to start with the simplest implementation (ARRAY) initially, |
|
|
and switch to a more suitable implementation after profiling your application. |
|
|
The implementation of each container instance is specified in a single place |
|
|
only: in the invocation of the function @code{gl_*_create_empty} that creates |
|
|
the instance. |
|
|
|
|
|
@subsubsection Sequential lists |
|
|
|
|
|
The implementations and the guaranteed average performance for the operations |
|
|
for the ``sequential list'' data type are: |
|
|
|
|
|
@ifinfo |
|
|
@noindent |
|
|
Note: This table is overloaded in the @command{info}-formatted documentation. |
|
|
It is better viewable in the HTML-formatted documentation. |
|
|
@end ifinfo |
|
|
|
|
|
@multitable @columnfractions 0.2 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 |
|
|
@headitem Operation |
|
|
@tab ARRAY |
|
|
@tab CARRAY |
|
|
@tab LINKED |
|
|
@tab TREE |
|
|
@tab LINKEDHASH with duplicates |
|
|
@tab LINKEDHASH without duplicates |
|
|
@tab TREEHASH with duplicates |
|
|
@tab TREEHASH without duplicates |
|
|
@item @code{gl_list_size} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_list_node_value} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_list_node_set_value} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_list_next_node} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_previous_node} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_first_node} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_last_node} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_get_at} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_get_first} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_get_last} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_set_at} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_set_first} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_set_last} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_search} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_list_search_from} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_search_from_to} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_indexof} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_indexof_from} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_indexof_from_to} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_add_first} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_add_last} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_add_before} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_add_after} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_add_at} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_remove_node} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_remove_at} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_remove_first} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_remove_last} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_remove} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_iterator} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_iterator_from_to} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_list_iterator_next} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_sortedlist_search} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_sortedlist_search_from} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_sortedlist_indexof} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_sortedlist_indexof_from} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_sortedlist_add} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_sortedlist_remove} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O((@log n)@mathopsup{2})} |
|
|
@tab @math{O(@log n)} |
|
|
@end multitable |
|
|
|
|
|
The Gnulib modules for sequential lists are: |
|
|
|
|
|
@mindex list |
|
|
@mindex xlist |
|
|
@mindex array-list |
|
|
@mindex carray-list |
|
|
@mindex linked-list |
|
|
@mindex avltree-list |
|
|
@mindex rbtree-list |
|
|
@mindex linkedhash-list |
|
|
@mindex avltreehash-list |
|
|
@mindex rbtreehash-list |
|
|
@mindex sublist |
|
|
@mindex xsublist |
|
|
@multitable @columnfractions 0.3 0.7 |
|
|
@headitem Implementation @tab Modules |
|
|
@item Abstract @tab @code{list}, @code{xlist} |
|
|
@item ARRAY @tab @code{array-list} |
|
|
@item CARRAY @tab @code{carray-list} |
|
|
@item LINKED @tab @code{linked-list} |
|
|
@item TREE @tab @code{avltree-list}, @code{rbtree-list} |
|
|
@item LINKEDHASH @tab @code{linkedhash-list} |
|
|
@item TREEHASH @tab @code{avltreehash-list}, @code{rbtreehash-list} |
|
|
@item Portion of a list @tab @code{sublist}, @code{xsublist} |
|
|
@end multitable |
|
|
|
|
|
@subsubsection Sets |
|
|
|
|
|
The implementations and the guaranteed average performance for the operations |
|
|
for the ``set'' data type are: |
|
|
|
|
|
@multitable @columnfractions 0.4 0.2 0.4 |
|
|
@headitem Operation |
|
|
@tab ARRAY |
|
|
@tab LINKEDHASH, HASH |
|
|
@item @code{gl_set_size} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_set_add} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_set_remove} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_set_search} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_set_iterator} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_set_iterator_next} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@end multitable |
|
|
|
|
|
The Gnulib modules for sets are: |
|
|
|
|
|
@mindex set |
|
|
@mindex xset |
|
|
@mindex array-set |
|
|
@mindex linkedhash-set |
|
|
@mindex hash-set |
|
|
@multitable @columnfractions 0.3 0.7 |
|
|
@headitem Implementation @tab Modules |
|
|
@item Abstract @tab @code{set}, @code{xset} |
|
|
@item ARRAY @tab @code{array-set} |
|
|
@item LINKEDHASH @tab @code{linkedhash-set} |
|
|
@item HASH @tab @code{hash-set} |
|
|
@end multitable |
|
|
|
|
|
@subsubsection Ordered sets |
|
|
|
|
|
The implementations and the guaranteed average performance for the operations |
|
|
for the ``ordered set'' data type are: |
|
|
|
|
|
@multitable @columnfractions 0.5 0.25 0.25 |
|
|
@headitem Operation |
|
|
@tab ARRAY |
|
|
@tab TREE |
|
|
@item @code{gl_oset_size} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_oset_add} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_oset_remove} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_oset_search} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_oset_search_atleast} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_oset_iterator} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_oset_iterator_next} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@end multitable |
|
|
|
|
|
The Gnulib modules for ordered sets are: |
|
|
|
|
|
@mindex oset |
|
|
@mindex xoset |
|
|
@mindex array-oset |
|
|
@mindex avltree-oset |
|
|
@mindex rbtree-oset |
|
|
@multitable @columnfractions 0.3 0.7 |
|
|
@headitem Implementation @tab Modules |
|
|
@item Abstract @tab @code{oset}, @code{xoset} |
|
|
@item ARRAY @tab @code{array-oset} |
|
|
@item TREE @tab @code{avltree-oset}, @code{rbtree-oset} |
|
|
@end multitable |
|
|
|
|
|
@subsubsection Maps |
|
|
|
|
|
The implementations and the guaranteed average performance for the operations |
|
|
for the ``map'' data type are: |
|
|
|
|
|
@multitable @columnfractions 0.4 0.2 0.4 |
|
|
@headitem Operation |
|
|
@tab ARRAY |
|
|
@tab LINKEDHASH, HASH |
|
|
@item @code{gl_map_size} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_map_get} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_map_put} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_map_remove} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_map_search} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_map_iterator} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_map_iterator_next} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@end multitable |
|
|
|
|
|
The Gnulib modules for maps are: |
|
|
|
|
|
@mindex map |
|
|
@mindex xmap |
|
|
@mindex array-map |
|
|
@mindex linkedhash-map |
|
|
@mindex hash-map |
|
|
@multitable @columnfractions 0.3 0.7 |
|
|
@headitem Implementation @tab Modules |
|
|
@item Abstract @tab @code{map}, @code{xmap} |
|
|
@item ARRAY @tab @code{array-map} |
|
|
@item LINKEDHASH @tab @code{linkedhash-map} |
|
|
@item HASH @tab @code{hash-map} |
|
|
@end multitable |
|
|
|
|
|
@subsubsection Ordered maps |
|
|
|
|
|
The implementations and the guaranteed average performance for the operations |
|
|
for the ``ordered map'' data type are: |
|
|
|
|
|
@multitable @columnfractions 0.5 0.25 0.25 |
|
|
@headitem Operation |
|
|
@tab ARRAY |
|
|
@tab TREE |
|
|
@item @code{gl_omap_size} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(1)} |
|
|
@item @code{gl_omap_get} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_omap_put} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_omap_remove} |
|
|
@tab @math{O(n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_omap_search} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_omap_search_atleast} |
|
|
@tab @math{O(@log n)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_omap_iterator} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@item @code{gl_omap_iterator_next} |
|
|
@tab @math{O(1)} |
|
|
@tab @math{O(@log n)} |
|
|
@end multitable |
|
|
|
|
|
The Gnulib modules for ordered maps are: |
|
|
|
|
|
@mindex omap |
|
|
@mindex xomap |
|
|
@mindex array-omap |
|
|
@mindex avltree-omap |
|
|
@mindex rbtree-omap |
|
|
@multitable @columnfractions 0.3 0.7 |
|
|
@headitem Implementation @tab Modules |
|
|
@item Abstract @tab @code{omap}, @code{xomap} |
|
|
@item ARRAY @tab @code{array-omap} |
|
|
@item TREE @tab @code{avltree-omap}, @code{rbtree-omap} |
|
|
@end multitable |
|
|
|
|
|
@subsubsection C++ classes for container data types |
|
|
|
|
|
For C++, Gnulib provides a C++ template class for each of these container data types. |
|
|
|
|
|
@mindex list-c++ |
|
|
@mindex set-c++ |
|
|
@mindex oset-c++ |
|
|
@mindex map-c++ |
|
|
@mindex omap-c++ |
|
|
@multitable @columnfractions .30 .20 .25 .25 |
|
|
@headitem Data type |
|
|
@tab C++ class |
|
|
@tab Module |
|
|
@tab Include file |
|
|
@item Sequential list |
|
|
@tab @code{gl_List} |
|
|
@tab @code{list-c++} |
|
|
@tab @code{"gl_list.hh"} |
|
|
@item Set |
|
|
@tab @code{gl_Set} |
|
|
@tab @code{set-c++} |
|
|
@tab @code{"gl_set.hh"} |
|
|
@item Ordered set |
|
|
@tab @code{gl_OSet} |
|
|
@tab @code{oset-c++} |
|
|
@tab @code{"gl_oset.hh"} |
|
|
@item Map |
|
|
@tab @code{gl_Map} |
|
|
@tab @code{map-c++} |
|
|
@tab @code{"gl_map.hh"} |
|
|
@item Ordered map |
|
|
@tab @code{gl_OMap} |
|
|
@tab @code{omap-c++} |
|
|
@tab @code{"gl_omap.hh"} |
|
|
@end multitable |
|
|
|
|
|
@node Specialized containers |
|
|
@subsection Specialized container data types |
|
|
|
|
|
@mindex hamt |
|
|
The @code{hamt} module implements the hash array mapped trie (HAMT) data |
|
|
structure. This is a data structure that contains (key, value) pairs. |
|
|
Lookup of a (key, value) pair given the key is on average an @math{O(1)} |
|
|
operation, assuming a good hash function for the keys is employed. |
|
|
|
|
|
The HAMT data structure is useful when you want modifications (additions |
|
|
of pairs, removal, value changes) to be visible only to some part of |
|
|
your program, whereas other parts of the program continue to use the |
|
|
unmodified HAMT. The HAMT makes this possible in a space-efficient |
|
|
manner: the modified and the unmodified HAMT share most of their |
|
|
allocated memory. It is also time-efficient: Every such modification |
|
|
is @math{O(1)} on average, again assuming a good hash function for the keys. |
|
|
|
|
|
A HAMT can be used whenever an ordinary hash table would be used. It |
|
|
does however, provide non-destructive updating operations without the |
|
|
need to copy the whole container. On the other hand, a hash table is |
|
|
simpler so that its performance may be better when non-destructive |
|
|
update operations are not needed. |
|
|
|
|
|
For example, a HAMT can be used to model the dynamic environment in a |
|
|
LISP interpreter. Updating a value in the dynamic environment of one |
|
|
continuation frame would not modify values in earlier frames. |
|
|
|
|
|
To use the module, include @code{hamt.h} in your code. The public |
|
|
interface is documented in that header file. You have to provide a hash |
|
|
function and an equivalence relation, which defines key equality. The |
|
|
module includes a test file @code{test-hamt.c}, which demonstrates how |
|
|
the API can be used. |
|
|
|
|
|
In the current implementation, each inner node of the HAMT can store up |
|
|
to @math{32 = 2^5} entries and subtries. Whenever a collision between |
|
|
the initial bits of the hash values of two entries would happen, the |
|
|
next @math{5} bits of the hash values are examined and the two entries |
|
|
pushed down one level in the trie. |
|
|
|
|
|
HAMTs have the same average access times as hash tables but grow and |
|
|
shrink dynamically, so they use memory more economically and do not have |
|
|
to be periodically resized. |
|
|
|
|
|
They were described and analyzed in @cite{Phil Bagwell (2000). Ideal |
|
|
Hash Trees (Report). Infoscience Department, École Polytechnique |
|
|
Fédérale de Lausanne.} |
|
|
|
|
|
The persistence aspect of the HAMT data structure, which means that each |
|
|
updating operation (like inserting, replacing, or removing an entry) |
|
|
returns a new HAMT while leaving the original one intact, is achieved |
|
|
through structure sharing, which is even safe in the presence of |
|
|
multiple threads when the used C compiler supports atomics. |
|
|
|
|
|
@ifnottex |
|
|
@unmacro log |
|
|
@end ifnottex |
|
|
@ifhtml |
|
|
@unmacro mathopsup |
|
|
@end ifhtml |
|
|
@ifinfo |
|
|
@unmacro mathopsup |
|
|
@end ifinfo |
|
|
|