1025598e |
1 | .\" -*-nroff-*- |
2 | .de VS |
3 | .sp 1 |
4 | .RS |
5 | .nf |
6 | .ft B |
7 | .. |
8 | .de VE |
9 | .ft R |
10 | .fi |
11 | .RE |
12 | .sp 1 |
13 | .. |
fbf20b5b |
14 | .TH assoc 3 "23 January 2001" "Straylight/Edgeware" "mLib utilities library" |
1025598e |
15 | .SH NAME |
16 | assoc \- tables indexed by atoms |
17 | .\" @assoc_create |
18 | .\" @assoc_destroy |
19 | .\" @assoc_find |
20 | .\" @assoc_remove |
21 | .\" @assoc_mkiter |
22 | .\" @assoc_next |
23 | .\" |
24 | .\" @ASSOC_ATOM |
25 | .\" |
26 | .SH SYNOPSIS |
27 | .nf |
28 | .B "#include <mLib/assoc.h>" |
29 | |
30 | .BI "void assoc_create(assoc_table *" t ); |
31 | .BI "void assoc_destroy(assoc_table *" t ); |
32 | |
33 | .BI "void *assoc_find(assoc_table *" t ", atom *" a ", size_t " sz ", unsigned *" f ); |
34 | .BI "void assoc_remove(assoc_table *" t ", void *" b ); |
35 | |
36 | .BI "atom *ASSOC_ATOM(const void *" p ); |
37 | |
38 | .BI "void assoc_mkiter(assoc_iter *" i ", assoc_table *" t ); |
39 | .BI "void *assoc_next(assoc_iter *" i ); |
40 | .fi |
41 | .SH DESCRIPTION |
42 | An |
43 | .I "association table" |
44 | is a data structure which maps atoms (see |
45 | .BR atom (3)) |
46 | to arbitrary values. It works in a similar way to the symbol tables |
47 | implemented by |
48 | .BR sym (3), |
49 | except that it uses atoms rather than blocks of data as keys. |
50 | .PP |
51 | Like |
52 | .BR sym (3), |
53 | it implements an |
54 | .I intrusive |
55 | table: the value structures must include an |
56 | .B assoc_base |
57 | structure. |
58 | .PP |
59 | There are three main data structures: |
60 | .TP |
61 | .B assoc_table |
62 | Keeps track of the information associated with a particular table. |
63 | .TP |
64 | .B assoc_base |
65 | The header which must be attached to the front of all the value objects. |
66 | .TP |
67 | .B assoc_iter |
68 | An iterator object, used for enumerating all of the associations stored |
69 | in the table |
70 | .PP |
71 | All of the above structures should be considered |
72 | .IR opaque : |
73 | don't try looking inside. |
74 | .SS "Creation and destruction" |
75 | The |
76 | .B assoc_table |
77 | object itself needs to be allocated by the caller. It is initialized by |
78 | passing it to the function |
79 | .BR assoc_create . |
80 | After initialization, the table contains no entries. |
81 | .PP |
82 | Initializing an association table involves allocating some memory. If |
83 | this allocation fails, an |
84 | .B EXC_NOMEM |
85 | exception is raised. |
86 | .PP |
87 | When an association table is no longer needed, the memory occupied by |
88 | the values and other maintenance structures can be reclaimed by calling |
89 | .BR assoc_destroy . |
90 | Any bits of user data attached to values should previously have been |
91 | destroyed. |
92 | .SS "Adding, searching and removing" |
93 | Most of the actual work is done by the function |
94 | .BR assoc_find . |
95 | It does both lookup and creation, depending on its arguments. To do its |
96 | job, it needs to know the following bits of information: |
97 | .TP |
98 | .BI "assoc_table *" t |
99 | A pointer to an association table to manipulate. |
100 | .TP |
101 | .BI "atom *" a |
102 | The address of the atom to use as a key. |
103 | .TP |
104 | .BI "size_t " sz |
105 | The size of the value block to allocate if the key could not be found. |
106 | If this is zero, no value is allocated, and a null pointer is returned |
107 | to indicate an unsuccessful lookup. |
108 | .TP |
109 | .BI "unsigned *" f |
110 | The address of a `found' flag to set. This is an output parameter. On |
111 | exit, |
112 | .B assoc_find |
113 | will set the value of |
114 | .BI * f |
115 | to zero if the key could not be found, or nonzero if it was found. This |
116 | can be used to tell whether the value returned has been newly allocated, |
117 | or whether it was already in the table. |
118 | .PP |
119 | A symbol can be removed from the table by calling |
120 | .BR assoc_remove , |
121 | passing the association table itself, and the value block that needs |
122 | removing. |
123 | .SS "Enquiries about associations" |
124 | Given a pointer |
125 | .I a |
126 | to an association, the expression |
127 | .BI ASSOC_ATOM( a ) |
128 | has as its value a poinetr to the atom which is that association's key. |
129 | .SS "Enumerating associations" |
130 | Enumerating the values in an association table is fairly simple. |
131 | Allocate an |
132 | .B assoc_iter |
133 | object from somewhere. Attach it to an association table by calling |
134 | .BR assoc_mkiter , |
135 | and passing in the addresses of the iterator and the symbol table. |
136 | Then, each call to |
137 | .B assoc_next |
138 | will return a different value from the association table, until all of |
139 | them have been enumerated, at which point, |
140 | .B assoc_next |
141 | returns a null pointer. |
142 | .PP |
143 | It's safe to remove the symbol you've just been returned by |
144 | .BR assoc_next . |
145 | However, it's not safe to remove any other symbol. So don't do that. |
146 | .PP |
147 | When you've finished with an iterator, it's safe to just throw it away. |
148 | You don't need to call any functions beforehand. |
149 | .SH SEE ALSO |
150 | .BR atom (3), |
151 | .BR hash (3), |
152 | .BR sym (3), |
153 | .BR mLib (3). |
154 | .SH AUTHOR |
155 | Mark Wooding, <mdw@nsict.org> |