9f65b8ee76b84125d1bdf61a83db63187f91dafc
[mLib] / struct / assoc.3
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 ..
14 .TH assoc 3 "23 January 2001" "Straylight/Edgeware" "mLib utilities library"
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 .PP
30 .B "typedef struct { ...\& } assoc_table;"
31 .B "typedef struct { ...\& } assoc_base;"
32 .PP
33 .BI "void assoc_create(assoc_table *" t );
34 .BI "void assoc_destroy(assoc_table *" t );
35 .PP
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 .PP
39 .BI "atom *ASSOC_ATOM(const void *" p );
40 .PP
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
158 Mark Wooding, <mdw@distorted.org.uk>