part of the UI
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Thu, 29 May 2003 13:18:42 +0000 (13:18 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Thu, 29 May 2003 13:18:42 +0000 (13:18 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@14 04897980-b3bd-0310-b5e0-8ef037075253

ltt/branches/poly/lttv/attribute.c [new file with mode: 0644]

diff --git a/ltt/branches/poly/lttv/attribute.c b/ltt/branches/poly/lttv/attribute.c
new file mode 100644 (file)
index 0000000..b400804
--- /dev/null
@@ -0,0 +1,423 @@
+#include <lttv/attribute.h>
+
+inline lttv_string_id lttv_string_id_from_string(const char *s) {
+  return g_quark_from_string(s);
+}
+
+
+inline void lttv_string_id_release(lttv_string_id i) {}
+
+
+inline const char *lttv_string_id_to_string(lttv_string_id i) {
+  return g_quark_to_string(i);
+}
+
+
+inline lttv_key *lttv_key_new() {
+  return g_array_new(FALSE, FALSE, sizeof(lttv_string_id));
+}
+
+/* Changed this function to destroy the element also, caused memory leak? */
+/* Mathieu Desnoyers */
+inline void lttv_key_destroy(lttv_key *k) {
+  g_array_free(k, TRUE);
+}
+
+
+#define _lttv_key_index(k,i) g_array_index(k, lttv_string_id, i)
+
+
+inline void lttv_key_append(lttv_key *k, lttv_string_id i) {
+  g_array_append_val(k,i);
+}
+
+
+inline unsigned int lttv_key_component_number(lttv_key *k) {
+  return k->len;
+}
+
+
+lttv_key *lttv_key_copy(lttv_key *k) {
+  lttv_key *nk;
+  int i;
+
+  nk = lttv_key_new();
+  for(i = 0 ; i < k->len ; i++) lttv_key_append(nk,lttv_key_index(k,i));
+  return nk;
+}
+
+/* It is also possible to create a key directly from a pathname,
+   key components separated by /, (e.g., "/hooks/options/before"). */
+
+lttv_key *lttv_key_new_pathname(const char *p) {
+  char **v, **cursor;
+  lttv_key *k;
+
+  v = cursor = g_strsplit(p, "/", -1);
+  k = lttv_key_new();
+
+  while(*cursor != NULL) {
+    lttv_key_append(k, lttv_string_id_from_string(*cursor));
+    cursor++;
+  }
+  g_strfreev(v);
+  return k;
+}
+
+static guint lttv_key_hash(gconstpointer key) {
+  lttv_key * k = (lttv_key *)key;
+  guint h = 0;
+  int i;
+  for(i = 0 ; i < k->len ; i++) h = h ^ lttv_key_index(k,i);
+  return h;
+}
+
+static gboolean lttv_key_equal(gconstpointer key1,gconstpointer key2) {
+  lttv_key * k1 = (lttv_key *)key1;
+  lttv_key * k2 = (lttv_key *)key2;  
+  int i;
+
+  if(k1->len != k2->len) return FALSE;
+  for(i = 0 ; i < k1->len ; i++) 
+    if(lttv_key_index(k1,i) != lttv_key_index(k2,i)) return FALSE;
+  return TRUE;
+}
+
+
+static void lttv_key_free(gpointer data)
+{
+  lttv_key_destroy((lttv_key *)data);
+}
+
+
+static void lttv_attribute_value_free(gpointer data) 
+{
+  g_free(data);
+}
+
+
+lttv_attributes *lttv_attributes_new() {
+  lttv_attributes *a;
+
+  a = g_new(lttv_attributes, 1);
+  a->ints = g_hash_table_new_full(lttv_key_hash, lttv_key_equal,
+      lttv_key_free, lttv_attribute_value_free);
+  a->times = g_hash_table_new_full(lttv_key_hash, lttv_key_equal,
+      lttv_key_free, lttv_attribute_value_free);
+  a->doubles = g_hash_table_new_full(lttv_key_hash, lttv_key_equal,
+      lttv_key_free, lttv_attribute_value_free);
+  a->pointers = g_hash_table_new(lttv_key_hash, lttv_key_equal);
+
+  return a;
+}
+
+
+/* Free the hash table containing the stats and all the contained keys/vals */
+
+static void lttv_attribute_key_free(gpointer k, gpointer v, gpointer data) {
+  lttv_key_free(k);
+}
+
+
+void lttv_attributes_destroy(lttv_attributes *a) {
+  g_hash_table_destroy(a->ints);
+  g_hash_table_destroy(a->times);
+  g_hash_table_destroy(a->doubles);
+
+  g_hash_table_foreach(a->pointers, lttv_attribute_key_free, NULL);
+  g_hash_table_destroy(a->pointers);
+  g_free(a);
+}
+
+unsigned int lttv_attributes_number(lttv_attributes *a) {
+  return g_hash_table_size(a->ints) + g_hash_table_size(a->times) +
+      g_hash_table_size(a->doubles) + g_hash_table_size(a->pointers);
+}
+
+
+/* If it is a new entry, insert it in the hash table, and set it to 0 */
+
+int *lttv_attributes_get_integer(lttv_attributes *a, lttv_key *k) 
+{
+  gpointer found;
+
+  found = g_hash_table_lookup(a->ints, k);
+  if(found == NULL) {
+    found = g_new(gint, 1);
+    *(gint *)found = 0;
+    g_hash_table_insert(a->ints, lttv_key_copy(k), found);
+  }
+  return found;
+}
+
+
+lttv_time *lttv_attributes_get_time(lttv_attributes *a, lttv_key *k) 
+{
+  gpointer found;
+  
+  found = g_hash_table_lookup(a->times, k);
+  if(found == NULL) {
+    found = g_new0(lttv_time, 1);
+    /*    *(lttv_time *)found = ZeroTime; */
+    g_hash_table_insert(a->times, lttv_key_copy(k), found);
+  }
+  return found;
+}
+
+double *lttv_attributes_get_double(lttv_attributes *a, lttv_key *k) 
+{
+  gpointer found;
+
+  found = g_hash_table_lookup(a->doubles,k);
+  if(found == NULL) {
+    found = g_new(double,1);
+    *(double *)found = 0;
+    g_hash_table_insert(a->doubles, lttv_key_copy(k),found);
+  }
+  return found;
+}
+
+void *lttv_attributes_get_pointer_pathname(lttv_attributes *a, char *pn) 
+{
+  lttv_key *key;
+  void *p;
+
+  key = lttv_key_new_pathname(pn);
+  p = lttv_attributes_get_pointer(a, key);
+  lttv_key_destroy(key);
+
+  return p;
+}
+
+void *lttv_attributes_get_pointer(lttv_attributes *a, lttv_key *k) 
+{
+  return g_hash_table_lookup(a->pointers,k);
+}
+
+void lttv_attributes_set_pointer_pathname(lttv_attributes *a,char *pn,void *p)
+{
+  lttv_key *key = lttv_key_new_pathname(pn);
+  
+  lttv_attributes_set_pointer(a, key, p);
+  lttv_key_destroy(key);
+}
+
+void lttv_attributes_set_pointer(lttv_attributes *a, lttv_key *k, void *p) {
+  lttv_key * oldk;
+  void *oldv;
+
+  if(g_hash_table_lookup_extended(a->pointers, k, (gpointer)oldk, &oldv)) {
+    if(p == NULL) {
+      g_hash_table_remove(a->pointers,k);
+    } 
+    else {
+      g_hash_table_insert(a->pointers,oldk,p);
+    }
+  } 
+  else {
+    if(p == NULL) return;
+    g_hash_table_insert(a->pointers,lttv_key_copy(k),p);
+  }
+}
+
+
+/* Sometimes the attributes must be accessed in bulk, sorted in different
+   ways. For this purpose they may be converted to arrays and sorted
+   multiple times. The keys used in the array belong to the lttv_attributes
+   object from which the array was obtained and are freed when it is
+   destroyed. Each element in the array is an lttv_attribute, a structure
+   containing the key, the value type, and a union containing a value of
+   that type. Multiple attributes with equal keys may be possible in some
+   implementations if their type differs. */
+
+
+typedef struct _lttv_attribute_fill_position  {
+  unsigned i;
+  lttv_attribute_type t;
+  lttv_attribute *a;
+} lttv_attribute_fill_position;
+
+
+static void lttv_attribute_fill(void *key, void *value, void *user_data) {
+  lttv_attribute_fill_position * p = (lttv_attribute_fill_position *)user_data;
+  lttv_attribute *a = p->a + p->i;
+
+  a->key = (lttv_key *)key;
+  a->t = p->t;
+  switch(p->t) {
+    case LTTV_INTEGER:
+      a->v.i = *((int *)value);
+    case LTTV_TIME:
+      a->v.t = *((lttv_time *)value);
+    case LTTV_DOUBLE:
+      a->v.d = *((double *)value);
+    case LTTV_POINTER:
+      a->v.p = value;
+  }
+  p->i++;
+}
+
+
+lttv_attribute *lttv_attributes_array_get(lttv_attributes *a) {
+  unsigned size;
+  lttv_attribute *v;
+  lttv_attribute_fill_position p;
+
+  size = lttv_attributes_number(a);
+  v = g_new(lttv_attribute,size);
+
+  p.a = v;
+  p.i = 0;
+  p.t = LTTV_INTEGER;
+  g_hash_table_foreach(a->ints, lttv_attribute_fill, &p);
+  p.t = LTTV_TIME;
+  g_hash_table_foreach(a->times, lttv_attribute_fill, &p);
+  p.t = LTTV_DOUBLE;
+  g_hash_table_foreach(a->doubles, lttv_attribute_fill, &p);
+  p.t = LTTV_POINTER;
+  g_hash_table_foreach(a->pointers, lttv_attribute_fill, &p);
+  return v;
+}
+
+
+lttv_attribute *lttv_attribute_array_destroy(lttv_attribute *a) {
+  g_free(a);
+}
+
+
+void lttv_attribute_array_sort(lttv_attribute *a,
+    unsigned size, lttv_key_compare f,
+    void *compare_data)
+{
+  
+  g_qsort_with_data(a, size, sizeof(lttv_attribute), f, 
+      compare_data);
+}
+
+
+int lttv_key_compare_priority(lttv_key *a, lttv_key *b, void *compare_data)
+{
+  int i, res;
+  int *priority = (int *)compare_data;
+
+  g_assert(a->len == b->len);
+
+  for(i = 0 ; i < a->len ; i++) 
+  {
+    res = strcmp(lttv_string_id_to_string(lttv_key_index(a,priority[i])),
+        lttv_string_id_to_string(lttv_key_index(a,priority[i])));
+    if(res != 0) return res;
+  }
+  return 0;
+}
+
+
+typedef struct _select_data {
+  lttv_attributes *a;
+  lttv_key *k;
+  void *user_data;
+  lttv_key_select select;
+} select_data;
+
+static void select_integer(void *key, void *value, void *user_data);
+static void select_double(void *key, void *value, void *user_data);
+static void select_time(void *key, void *value, void *user_data);
+static void select_pointer(void *key, void *value, void *user_data);
+
+lttv_attributes *lttv_attributes_select(lttv_attributes *a, lttv_key_select f, 
+    void *user_data)
+{
+  select_data *d;
+
+  d = g_new(select_data, 1);
+  d->a = lttv_attributes_new();
+  d->k = lttv_key_new();
+  d->user_data = user_data;
+  d->select = f;
+
+  g_hash_table_foreach(a->ints,select_integer, d);
+  g_hash_table_foreach(a->doubles,select_double, d);
+  g_hash_table_foreach(a->times,select_time, d);
+  g_hash_table_foreach(a->pointers,select_pointer, d);
+}
+
+int lttv_key_select_spec(lttv_key *in, lttv_key *out, void *user_data)
+{
+  lttv_key_select_spec_data *d = (lttv_key_select_spec_data *)user_data;
+  int i;
+
+  /* not defined yet */
+  /* lttv_key_set_size(out, 0); */
+
+  for(i = 0 ; i < d->length ; i++) {
+    switch(d->spec[i]) {
+    case LTTV_KEEP:
+      break;
+
+    case LTTV_KEEP_EQUAL:
+      break;
+
+    case LTTV_KEEP_SMALLER:
+      break;
+
+    case LTTV_KEEP_GREATER:
+      break;
+
+    case LTTV_IGNORE:
+      break;
+
+    }
+  }
+
+  return 1;
+}
+
+static void select_integer(void *key, void *value, void *user_data)
+{
+  lttv_key *k = (lttv_key *)key;
+  int *pi = (int *)value;
+  select_data *d = (select_data *)user_data;
+
+  if(d->select(k,d->k,d->user_data)) {
+    *(lttv_attributes_get_integer(d->a,d->k)) += *pi;
+  }
+}
+
+static void select_double(void *key, void *value, void *user_data)
+{
+  lttv_key *k = (lttv_key *)key;
+  double *pf = (double *)value;
+  select_data *d = (select_data *)user_data;
+
+  if(d->select(k,d->k,d->user_data)) {
+    *(lttv_attributes_get_double(d->a,d->k)) += *pf;
+  }
+}
+
+static void select_time(void *key, void *value, void *user_data)
+{
+  lttv_key *k = (lttv_key *)key;
+  lttv_time *ptSum, *pt = (lttv_time *)value;
+  select_data *d = (select_data *)user_data;
+
+  if(d->select(k,d->k,d->user_data)) {
+    ptSum = lttv_attributes_get_time(d->a,d->k);
+    ptSum->tv_sec += pt->tv_sec;
+    ptSum->tv_nsec += pt->tv_nsec;
+  }
+}
+
+static void select_pointer(void *key, void *value, void *user_data)
+{
+  lttv_key *k = (lttv_key *)key;
+  select_data *d = (select_data *)user_data;
+
+  if(d->select(k,d->k,d->user_data)) {
+    lttv_attributes_set_pointer(d->a,d->k,value);
+  }
+}
+
+
+
+
+
This page took 0.027845 seconds and 4 git commands to generate.