c5d77517 |
1 | #ifndef ATTRIBUTE_H |
2 | #define ATTRIBUTE_H |
3 | |
4 | |
5 | #include <glib.h> |
6 | #include <time.h> |
7 | |
8 | /* Attributes are used to store any value identified by a key. They are |
9 | typically used to store state information or accumulated statistics for |
10 | some object. Each value is accessed through a multi-component key, which |
11 | resembles hierarchical pathnames in filesystems. |
12 | |
13 | The attributes may store integers, doubles or time values, in which case |
14 | the values are created upon first access of a key and with a default |
15 | value of 0. Pointer values are also available with a default value of NULL |
16 | and must thus be set explicitely to user managed (statically or dynamically |
17 | allocated) memory. */ |
18 | |
19 | |
20 | typedef guint32 lttv_string_id; |
21 | |
22 | typedef GArray _lttv_key; |
23 | |
24 | typedef _lttv_key lttv_key; |
25 | |
26 | typedef struct timespec lttv_time; |
27 | |
28 | |
29 | typedef struct _lttv_attributes { |
30 | GHashTable *ints; |
31 | GHashTable *times; |
32 | GHashTable *doubles; |
33 | GHashTable *pointers; |
34 | } lttv_attributes; |
35 | |
36 | |
37 | /* A unique integer identifier represents each different string |
38 | used as a key component. A single copy of each different string is |
39 | stored but its usage count is incremented each time the corresponding id |
40 | is returned by lttv_string_id_from_string. The usage count is decremented |
41 | each time an id is released. */ |
42 | |
43 | lttv_string_id lttv_string_id_from_string(const char *s); |
44 | |
45 | void lttv_string_id_release(lttv_string_id i); |
46 | |
47 | const char *lttv_string_id_to_string(lttv_string_id i); |
48 | |
49 | |
50 | /* Keys are created and subsequently filled with key components */ |
51 | |
52 | lttv_key *lttv_key_new(); |
53 | |
54 | void lttv_key_destroy(lttv_key *k); |
55 | |
56 | /* macro to access/replace a the i th component of key k */ |
57 | |
58 | #define lttv_key_index(k,i) _lttv_key_index(k,i) |
59 | |
60 | |
61 | /* Append a new component */ |
62 | |
63 | void lttv_key_append(lttv_key *k, lttv_string_id i); |
64 | |
65 | |
66 | /* Number of components in a key */ |
67 | |
68 | unsigned int lttv_key_number(lttv_key *k); |
69 | |
70 | |
71 | /* It is also possible to create a key directly from a pathname, |
72 | key components separated by /, (e.g., "/hooks/options/before"). */ |
73 | |
74 | lttv_key *lttv_key_new_pathname(const char *pathname); |
75 | |
76 | |
77 | /* Create a new set of attributes */ |
78 | |
79 | lttv_attributes *lttv_attributes_new(); |
80 | |
81 | |
82 | /* Destroy the set of attributes including all the memory allocated |
83 | internally for it (copies of keys, and integer, double and time |
84 | values...). */ |
85 | |
86 | void lttv_attributes_destroy(lttv_attributes *a); |
87 | |
88 | |
89 | /* Total number of attributes in a lttv_attributes. */ |
90 | |
91 | unsigned int lttv_attributes_number(lttv_attributes *a); |
92 | |
93 | |
94 | /* Obtain a pointer to the value of the corresponding type associated with |
95 | the specified key. New values are created on demand with 0 as initial |
96 | value. These values are freed when the attributes set is destroyed. */ |
97 | |
98 | int *lttv_attributes_get_integer(lttv_attributes *a, lttv_key *k); |
99 | |
100 | lttv_time *lttv_attributes_get_time(lttv_attributes *a, lttv_key *k); |
101 | |
102 | double *lttv_attributes_get_double(lttv_attributes *a, lttv_key *k); |
103 | |
104 | |
105 | /* Set or get the pointer value associated with the specified key. |
106 | NULL is returned if no pointer was set for the key. */ |
107 | |
108 | void *lttv_attributes_get_pointer(lttv_attributes *a, lttv_key *k); |
109 | |
110 | void lttv_attributes_set_pointer(lttv_attributes *a, lttv_key *k, void *p); |
111 | |
112 | void *lttv_attributes_get_pointer_pathname(lttv_attributes *a, char *pn); |
113 | |
114 | void lttv_attributes_set_pointer_pathname(lttv_attributes *a,char *pn,void *p); |
115 | |
116 | |
1b82f325 |
117 | /* It is often useful to copy over some elements from the source attributes |
118 | table to the destination table. While doing so, constraints on each key |
119 | component may be used to select the elements of interest. Finally, some |
120 | numerical elements may need to be summed, for example summing the number |
121 | of page faults over all processes. A flexible function to copy attributes |
122 | may be used for all these operations. |
123 | |
124 | If the key of the element copied already exists in the destination |
125 | attributes, numerical values (integer, double or time) are summed and |
126 | pointers are replaced. |
127 | |
128 | The lttv_key_select_data structure specifies for each key component the |
129 | test applied to decide to copy or not the corresponding element. |
130 | It contains the relation to apply to each key component, the rel vector, |
131 | and the comparison key, both of size length. To decide if an element |
132 | should be copied, each component of its key is compared with the |
133 | comparison key, and the relation specified for each component must |
134 | be verified. The relation ANY is always verified and the comparison key |
135 | component is not used. The relation NONE is only verified if the key |
136 | examined contains fewer components than the position examined. The EQ, NE, |
137 | LT, LE, GT, GE relations are verified if the key is long enough and the |
138 | component satisfies the relation with respect to the comparison key. |
139 | Finally, the CUT relation is satisfied if the key is long enough, but the |
140 | element is copied with that component removed from its key. All the keys |
141 | which only differ by that component become identical after being shortened |
142 | and their numerical values are thus summed when copied. */ |
143 | |
144 | typedef enum _lttv_key_select_relation |
145 | { LTTV_KEY_ANY, /* Any value is good */ |
146 | LTTV_KEY_NONE, /* No value is good, i.e. the key must be shorter */ |
147 | LTTV_KEY_EQ, /* key[n] is equal to match[n] */ |
148 | LTTV_KEY_NE, /* key[n] is not equal to match[n] */ |
149 | LTTV_KEY_LT, /* key[n] is lower than match[n] */ |
150 | LTTV_KEY_LE, /* key[n] is lower or equal than match[n] */ |
151 | LTTV_KEY_GT, /* key[n] is greater than match[n] */ |
152 | LTTV_KEY_GE, /* key[n] is greater or equal than match[n] */ |
153 | LTTV_KEY_CUT /* cut key[n], shortening the key for the copy */ |
154 | } lttv_key_select_relation; |
155 | |
156 | typedef struct _lttv_key_select_data |
c5d77517 |
157 | { |
158 | unsigned length; |
1b82f325 |
159 | lttv_key_select_relation *rel; |
160 | lttv_key *comparison; |
161 | } lttv_key_select_data; |
c5d77517 |
162 | |
1b82f325 |
163 | void lttv_attributes_copy(lttv_attributes *src, lttv_attributes *dest, |
164 | lttv_key_select_data d); |
c5d77517 |
165 | |
166 | |
167 | /* Sometimes the attributes must be accessed in bulk, sorted in different |
168 | ways. For this purpose they may be converted to arrays and sorted |
169 | multiple times. The keys used in the array belong to the lttv_attributes |
170 | object from which the array was obtained and are freed when it is |
171 | destroyed. Each element in the array is an lttv_attribute, a structure |
172 | containing the key, the value type, and a union containing a value of |
173 | that type. Multiple attributes with equal keys may be possible in some |
174 | implementations if their type differs. */ |
175 | |
176 | |
177 | typedef enum _lttv_attribute_type |
178 | { LTTV_INTEGER, LTTV_TIME, LTTV_DOUBLE, LTTV_POINTER } |
179 | lttv_attribute_type; |
180 | |
181 | typedef union _lttv_value_any |
182 | { int i; |
183 | lttv_time t; |
184 | double d; |
185 | void *p; |
186 | } lttv_value_any; |
187 | |
188 | typedef struct _lttv_attribute { |
189 | lttv_key *key; |
190 | lttv_attribute_type t; |
191 | lttv_value_any v; |
192 | } lttv_attribute; |
193 | |
194 | |
c5d77517 |
195 | /* Obtain all the attributes in an array */ |
196 | |
197 | lttv_attribute *lttv_attributes_array_get(lttv_attributes *a); |
198 | |
199 | lttv_attribute *lttv_attribute_array_destroy(lttv_attribute *a); |
200 | |
1b82f325 |
201 | |
202 | /* The sorting order is determined by the supplied comparison function. |
203 | The comparison function must return a negative value if a < b, |
204 | 0 if a = b, and a positive if a > b. */ |
205 | |
206 | typedef int (*lttv_key_compare)(lttv_key *a, lttv_key *b, void *user_data); |
207 | |
c5d77517 |
208 | void lttv_attribute_array_sort(lttv_attribute *a, unsigned size, |
209 | lttv_key_compare f, void *user_data); |
210 | |
1b82f325 |
211 | |
212 | /* Sort in lexicographic order using the specified key components as primary, |
213 | secondary... keys. A vector containing the key components positions is |
214 | specified. */ |
215 | |
216 | int lttv_attribute_array_sort_lexicographic(lttv_attribute *a, unsigned size, |
217 | unsigned *positions, unsigned nb_positions); |
218 | |
c5d77517 |
219 | #endif // ATTRIBUTE_H |