Copies from older experiments which should not have been checked in.
[lttv.git] / ltt / branches / poly / lttv / attribute.c
CommitLineData
4accaa97 1#include "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
224/* Sometimes the attributes must be accessed in bulk, sorted in different
225 ways. For this purpose they may be converted to arrays and sorted
226 multiple times. The keys used in the array belong to the lttv_attributes
227 object from which the array was obtained and are freed when it is
228 destroyed. Each element in the array is an lttv_attribute, a structure
229 containing the key, the value type, and a union containing a value of
230 that type. Multiple attributes with equal keys may be possible in some
231 implementations if their type differs. */
232
233
234typedef struct _lttv_attribute_fill_position {
235 unsigned i;
236 lttv_attribute_type t;
237 lttv_attribute *a;
238} lttv_attribute_fill_position;
239
240
241static void lttv_attribute_fill(void *key, void *value, void *user_data) {
242 lttv_attribute_fill_position * p = (lttv_attribute_fill_position *)user_data;
243 lttv_attribute *a = p->a + p->i;
244
245 a->key = (lttv_key *)key;
246 a->t = p->t;
247 switch(p->t) {
248 case LTTV_INTEGER:
249 a->v.i = *((int *)value);
250 case LTTV_TIME:
251 a->v.t = *((lttv_time *)value);
252 case LTTV_DOUBLE:
253 a->v.d = *((double *)value);
254 case LTTV_POINTER:
255 a->v.p = value;
256 }
257 p->i++;
258}
259
260
261lttv_attribute *lttv_attributes_array_get(lttv_attributes *a) {
262 unsigned size;
263 lttv_attribute *v;
264 lttv_attribute_fill_position p;
265
266 size = lttv_attributes_number(a);
267 v = g_new(lttv_attribute,size);
268
269 p.a = v;
270 p.i = 0;
271 p.t = LTTV_INTEGER;
272 g_hash_table_foreach(a->ints, lttv_attribute_fill, &p);
273 p.t = LTTV_TIME;
274 g_hash_table_foreach(a->times, lttv_attribute_fill, &p);
275 p.t = LTTV_DOUBLE;
276 g_hash_table_foreach(a->doubles, lttv_attribute_fill, &p);
277 p.t = LTTV_POINTER;
278 g_hash_table_foreach(a->pointers, lttv_attribute_fill, &p);
279 return v;
280}
281
282
283lttv_attribute *lttv_attribute_array_destroy(lttv_attribute *a) {
284 g_free(a);
285}
286
287
288void lttv_attribute_array_sort(lttv_attribute *a,
289 unsigned size, lttv_key_compare f,
290 void *compare_data)
291{
292
293 g_qsort_with_data(a, size, sizeof(lttv_attribute), f,
294 compare_data);
295}
296
297
298int lttv_key_compare_priority(lttv_key *a, lttv_key *b, void *compare_data)
299{
300 int i, res;
301 int *priority = (int *)compare_data;
302
303 g_assert(a->len == b->len);
304
305 for(i = 0 ; i < a->len ; i++)
306 {
307 res = strcmp(lttv_string_id_to_string(lttv_key_index(a,priority[i])),
308 lttv_string_id_to_string(lttv_key_index(a,priority[i])));
309 if(res != 0) return res;
310 }
311 return 0;
312}
313
314
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
This page took 0.036966 seconds and 4 git commands to generate.