icons
[lttv.git] / ltt / branches / poly / lttv / attribute.c
CommitLineData
fcdf0ec2 1#include <lttv/attribute.h>
f32847a1 2
3inline lttv_string_id lttv_string_id_from_string(const char *s) {
4 return g_quark_from_string(s);
5}
6
7
8inline void lttv_string_id_release(lttv_string_id i) {}
9
10
11inline const char *lttv_string_id_to_string(lttv_string_id i) {
12 return g_quark_to_string(i);
13}
14
15
16inline lttv_key *lttv_key_new() {
17 return g_array_new(FALSE, FALSE, sizeof(lttv_string_id));
18}
19
20/* Changed this function to destroy the element also, caused memory leak? */
21/* Mathieu Desnoyers */
22inline void lttv_key_destroy(lttv_key *k) {
23 g_array_free(k, TRUE);
24}
25
26
27#define _lttv_key_index(k,i) g_array_index(k, lttv_string_id, i)
28
29
30inline void lttv_key_append(lttv_key *k, lttv_string_id i) {
31 g_array_append_val(k,i);
32}
33
34
35inline unsigned int lttv_key_component_number(lttv_key *k) {
36 return k->len;
37}
38
39
40lttv_key *lttv_key_copy(lttv_key *k) {
41 lttv_key *nk;
42 int i;
43
44 nk = lttv_key_new();
45 for(i = 0 ; i < k->len ; i++) lttv_key_append(nk,lttv_key_index(k,i));
46 return nk;
47}
48
49/* It is also possible to create a key directly from a pathname,
50 key components separated by /, (e.g., "/hooks/options/before"). */
51
52lttv_key *lttv_key_new_pathname(const char *p) {
53 char **v, **cursor;
54 lttv_key *k;
55
56 v = cursor = g_strsplit(p, "/", -1);
57 k = lttv_key_new();
58
59 while(*cursor != NULL) {
60 lttv_key_append(k, lttv_string_id_from_string(*cursor));
61 cursor++;
62 }
63 g_strfreev(v);
64 return k;
65}
66
67static guint lttv_key_hash(gconstpointer key) {
68 lttv_key * k = (lttv_key *)key;
69 guint h = 0;
70 int i;
71 for(i = 0 ; i < k->len ; i++) h = h ^ lttv_key_index(k,i);
72 return h;
73}
74
75static gboolean lttv_key_equal(gconstpointer key1,gconstpointer key2) {
76 lttv_key * k1 = (lttv_key *)key1;
77 lttv_key * k2 = (lttv_key *)key2;
78 int i;
79
80 if(k1->len != k2->len) return FALSE;
81 for(i = 0 ; i < k1->len ; i++)
82 if(lttv_key_index(k1,i) != lttv_key_index(k2,i)) return FALSE;
83 return TRUE;
84}
85
86
87static void lttv_key_free(gpointer data)
88{
89 lttv_key_destroy((lttv_key *)data);
90}
91
92
93static void lttv_attribute_value_free(gpointer data)
94{
95 g_free(data);
96}
97
98
99lttv_attributes *lttv_attributes_new() {
100 lttv_attributes *a;
101
102 a = g_new(lttv_attributes, 1);
103 a->ints = g_hash_table_new_full(lttv_key_hash, lttv_key_equal,
104 lttv_key_free, lttv_attribute_value_free);
105 a->times = g_hash_table_new_full(lttv_key_hash, lttv_key_equal,
106 lttv_key_free, lttv_attribute_value_free);
107 a->doubles = g_hash_table_new_full(lttv_key_hash, lttv_key_equal,
108 lttv_key_free, lttv_attribute_value_free);
109 a->pointers = g_hash_table_new(lttv_key_hash, lttv_key_equal);
110
111 return a;
112}
113
114
115/* Free the hash table containing the stats and all the contained keys/vals */
116
117static void lttv_attribute_key_free(gpointer k, gpointer v, gpointer data) {
118 lttv_key_free(k);
119}
120
121
122void lttv_attributes_destroy(lttv_attributes *a) {
123 g_hash_table_destroy(a->ints);
124 g_hash_table_destroy(a->times);
125 g_hash_table_destroy(a->doubles);
126
127 g_hash_table_foreach(a->pointers, lttv_attribute_key_free, NULL);
128 g_hash_table_destroy(a->pointers);
129 g_free(a);
130}
131
132unsigned int lttv_attributes_number(lttv_attributes *a) {
133 return g_hash_table_size(a->ints) + g_hash_table_size(a->times) +
134 g_hash_table_size(a->doubles) + g_hash_table_size(a->pointers);
135}
136
137
138/* If it is a new entry, insert it in the hash table, and set it to 0 */
139
140int *lttv_attributes_get_integer(lttv_attributes *a, lttv_key *k)
141{
142 gpointer found;
143
144 found = g_hash_table_lookup(a->ints, k);
145 if(found == NULL) {
146 found = g_new(gint, 1);
147 *(gint *)found = 0;
148 g_hash_table_insert(a->ints, lttv_key_copy(k), found);
149 }
150 return found;
151}
152
153
154lttv_time *lttv_attributes_get_time(lttv_attributes *a, lttv_key *k)
155{
156 gpointer found;
157
158 found = g_hash_table_lookup(a->times, k);
159 if(found == NULL) {
160 found = g_new0(lttv_time, 1);
161 /* *(lttv_time *)found = ZeroTime; */
162 g_hash_table_insert(a->times, lttv_key_copy(k), found);
163 }
164 return found;
165}
166
167double *lttv_attributes_get_double(lttv_attributes *a, lttv_key *k)
168{
169 gpointer found;
170
171 found = g_hash_table_lookup(a->doubles,k);
172 if(found == NULL) {
173 found = g_new(double,1);
174 *(double *)found = 0;
175 g_hash_table_insert(a->doubles, lttv_key_copy(k),found);
176 }
177 return found;
178}
179
180void *lttv_attributes_get_pointer_pathname(lttv_attributes *a, char *pn)
181{
182 lttv_key *key;
183 void *p;
184
185 key = lttv_key_new_pathname(pn);
186 p = lttv_attributes_get_pointer(a, key);
187 lttv_key_destroy(key);
188
189 return p;
190}
191
192void *lttv_attributes_get_pointer(lttv_attributes *a, lttv_key *k)
193{
194 return g_hash_table_lookup(a->pointers,k);
195}
196
197void lttv_attributes_set_pointer_pathname(lttv_attributes *a,char *pn,void *p)
198{
199 lttv_key *key = lttv_key_new_pathname(pn);
200
201 lttv_attributes_set_pointer(a, key, p);
202 lttv_key_destroy(key);
203}
204
205void lttv_attributes_set_pointer(lttv_attributes *a, lttv_key *k, void *p) {
206 lttv_key * oldk;
207 void *oldv;
208
209 if(g_hash_table_lookup_extended(a->pointers, k, (gpointer)oldk, &oldv)) {
210 if(p == NULL) {
211 g_hash_table_remove(a->pointers,k);
212 }
213 else {
214 g_hash_table_insert(a->pointers,oldk,p);
215 }
216 }
217 else {
218 if(p == NULL) return;
219 g_hash_table_insert(a->pointers,lttv_key_copy(k),p);
220 }
221}
222
223
c27d48bb 224#ifdef EXT_ATTRIBS
f32847a1 225/* Sometimes the attributes must be accessed in bulk, sorted in different
226 ways. For this purpose they may be converted to arrays and sorted
227 multiple times. The keys used in the array belong to the lttv_attributes
228 object from which the array was obtained and are freed when it is
229 destroyed. Each element in the array is an lttv_attribute, a structure
230 containing the key, the value type, and a union containing a value of
231 that type. Multiple attributes with equal keys may be possible in some
232 implementations if their type differs. */
233
234
235typedef struct _lttv_attribute_fill_position {
236 unsigned i;
237 lttv_attribute_type t;
238 lttv_attribute *a;
239} lttv_attribute_fill_position;
240
241
242static void lttv_attribute_fill(void *key, void *value, void *user_data) {
243 lttv_attribute_fill_position * p = (lttv_attribute_fill_position *)user_data;
244 lttv_attribute *a = p->a + p->i;
245
246 a->key = (lttv_key *)key;
247 a->t = p->t;
248 switch(p->t) {
249 case LTTV_INTEGER:
250 a->v.i = *((int *)value);
251 case LTTV_TIME:
252 a->v.t = *((lttv_time *)value);
253 case LTTV_DOUBLE:
254 a->v.d = *((double *)value);
255 case LTTV_POINTER:
256 a->v.p = value;
257 }
258 p->i++;
259}
260
261
262lttv_attribute *lttv_attributes_array_get(lttv_attributes *a) {
263 unsigned size;
264 lttv_attribute *v;
265 lttv_attribute_fill_position p;
266
267 size = lttv_attributes_number(a);
268 v = g_new(lttv_attribute,size);
269
270 p.a = v;
271 p.i = 0;
272 p.t = LTTV_INTEGER;
273 g_hash_table_foreach(a->ints, lttv_attribute_fill, &p);
274 p.t = LTTV_TIME;
275 g_hash_table_foreach(a->times, lttv_attribute_fill, &p);
276 p.t = LTTV_DOUBLE;
277 g_hash_table_foreach(a->doubles, lttv_attribute_fill, &p);
278 p.t = LTTV_POINTER;
279 g_hash_table_foreach(a->pointers, lttv_attribute_fill, &p);
280 return v;
281}
282
283
284lttv_attribute *lttv_attribute_array_destroy(lttv_attribute *a) {
285 g_free(a);
286}
287
288
289void lttv_attribute_array_sort(lttv_attribute *a,
290 unsigned size, lttv_key_compare f,
291 void *compare_data)
292{
293
294 g_qsort_with_data(a, size, sizeof(lttv_attribute), f,
295 compare_data);
296}
297
298
299int lttv_key_compare_priority(lttv_key *a, lttv_key *b, void *compare_data)
300{
301 int i, res;
302 int *priority = (int *)compare_data;
303
304 g_assert(a->len == b->len);
305
306 for(i = 0 ; i < a->len ; i++)
307 {
308 res = strcmp(lttv_string_id_to_string(lttv_key_index(a,priority[i])),
309 lttv_string_id_to_string(lttv_key_index(a,priority[i])));
310 if(res != 0) return res;
311 }
312 return 0;
313}
314
f32847a1 315typedef struct _select_data {
316 lttv_attributes *a;
317 lttv_key *k;
318 void *user_data;
319 lttv_key_select select;
320} select_data;
321
322static void select_integer(void *key, void *value, void *user_data);
323static void select_double(void *key, void *value, void *user_data);
324static void select_time(void *key, void *value, void *user_data);
325static void select_pointer(void *key, void *value, void *user_data);
326
327lttv_attributes *lttv_attributes_select(lttv_attributes *a, lttv_key_select f,
328 void *user_data)
329{
330 select_data *d;
331
332 d = g_new(select_data, 1);
333 d->a = lttv_attributes_new();
334 d->k = lttv_key_new();
335 d->user_data = user_data;
336 d->select = f;
337
338 g_hash_table_foreach(a->ints,select_integer, d);
339 g_hash_table_foreach(a->doubles,select_double, d);
340 g_hash_table_foreach(a->times,select_time, d);
341 g_hash_table_foreach(a->pointers,select_pointer, d);
342}
343
344int lttv_key_select_spec(lttv_key *in, lttv_key *out, void *user_data)
345{
346 lttv_key_select_spec_data *d = (lttv_key_select_spec_data *)user_data;
347 int i;
348
349 /* not defined yet */
350 /* lttv_key_set_size(out, 0); */
351
352 for(i = 0 ; i < d->length ; i++) {
353 switch(d->spec[i]) {
354 case LTTV_KEEP:
355 break;
356
357 case LTTV_KEEP_EQUAL:
358 break;
359
360 case LTTV_KEEP_SMALLER:
361 break;
362
363 case LTTV_KEEP_GREATER:
364 break;
365
366 case LTTV_IGNORE:
367 break;
368
369 }
370 }
371
372 return 1;
373}
374
375static void select_integer(void *key, void *value, void *user_data)
376{
377 lttv_key *k = (lttv_key *)key;
378 int *pi = (int *)value;
379 select_data *d = (select_data *)user_data;
380
381 if(d->select(k,d->k,d->user_data)) {
382 *(lttv_attributes_get_integer(d->a,d->k)) += *pi;
383 }
384}
385
386static void select_double(void *key, void *value, void *user_data)
387{
388 lttv_key *k = (lttv_key *)key;
389 double *pf = (double *)value;
390 select_data *d = (select_data *)user_data;
391
392 if(d->select(k,d->k,d->user_data)) {
393 *(lttv_attributes_get_double(d->a,d->k)) += *pf;
394 }
395}
396
397static void select_time(void *key, void *value, void *user_data)
398{
399 lttv_key *k = (lttv_key *)key;
400 lttv_time *ptSum, *pt = (lttv_time *)value;
401 select_data *d = (select_data *)user_data;
402
403 if(d->select(k,d->k,d->user_data)) {
404 ptSum = lttv_attributes_get_time(d->a,d->k);
405 ptSum->tv_sec += pt->tv_sec;
406 ptSum->tv_nsec += pt->tv_nsec;
407 }
408}
409
410static void select_pointer(void *key, void *value, void *user_data)
411{
412 lttv_key *k = (lttv_key *)key;
413 select_data *d = (select_data *)user_data;
414
415 if(d->select(k,d->k,d->user_data)) {
416 lttv_attributes_set_pointer(d->a,d->k,value);
417 }
418}
419
420
421
422
423
c27d48bb 424#endif // EXT_ATTRIBS
This page took 0.036787 seconds and 4 git commands to generate.