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