X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Fattribute.c;h=eab857be844f1997b4dcea3635c6d913f7f0beb0;hb=f63ebe5196f36fcf40385d29cfc37288c4d70817;hp=a3f8ab9aecbdde8cd477428724cd971490d7719f;hpb=d8f124de0295aea546b6debf5945bfeea2bbeb2a;p=lttv.git diff --git a/ltt/branches/poly/lttv/lttv/attribute.c b/ltt/branches/poly/lttv/lttv/attribute.c index a3f8ab9a..eab857be 100644 --- a/ltt/branches/poly/lttv/lttv/attribute.c +++ b/ltt/branches/poly/lttv/lttv/attribute.c @@ -16,8 +16,14 @@ * MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include #include #include +#include typedef union _AttributeValue { int dv_int; @@ -37,10 +43,12 @@ typedef struct _Attribute { LttvAttributeName name; LttvAttributeType type; AttributeValue value; + gboolean is_named; } Attribute; -LttvAttributeValue address_of_value(LttvAttributeType t, AttributeValue *v) +static __inline__ LttvAttributeValue address_of_value(LttvAttributeType t, + AttributeValue *v) { LttvAttributeValue va; @@ -55,6 +63,7 @@ LttvAttributeValue address_of_value(LttvAttributeType t, AttributeValue *v) case LTTV_POINTER: va.v_pointer = &v->dv_pointer; break; case LTTV_STRING: va.v_string = &v->dv_string; break; case LTTV_GOBJECT: va.v_gobject = &v->dv_gobject; break; + case LTTV_NONE: break; } return va; } @@ -75,6 +84,7 @@ AttributeValue init_value(LttvAttributeType t) case LTTV_POINTER: v.dv_pointer = NULL; break; case LTTV_STRING: v.dv_string = NULL; break; case LTTV_GOBJECT: v.dv_gobject = NULL; break; + case LTTV_NONE: break; } return v; } @@ -86,7 +96,6 @@ lttv_attribute_get_number(LttvAttribute *self) return self->attributes->len; } - gboolean lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous) { @@ -94,16 +103,16 @@ lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous) return TRUE; } - LttvAttributeType lttv_attribute_get(LttvAttribute *self, unsigned i, LttvAttributeName *name, - LttvAttributeValue *v) + LttvAttributeValue *v, gboolean *is_named) { Attribute *a; a = &g_array_index(self->attributes, Attribute, i); *name = a->name; *v = address_of_value(a->type, &(a->value)); + *is_named = a->is_named; return a->type; } @@ -141,6 +150,30 @@ lttv_attribute_add(LttvAttribute *self, LttvAttributeName name, if(i != 0) g_error("duplicate entry in attribute table"); a.name = name; + a.is_named = 1; + a.type = t; + a.value = init_value(t); + g_array_append_val(self->attributes, a); + i = self->attributes->len - 1; + pa = &g_array_index(self->attributes, Attribute, i); + g_hash_table_insert(self->names, GUINT_TO_POINTER(name), + GUINT_TO_POINTER(i + 1)); + return address_of_value(t, &(pa->value)); +} + +LttvAttributeValue +lttv_attribute_add_unnamed(LttvAttribute *self, LttvAttributeName name, + LttvAttributeType t) +{ + unsigned i; + + Attribute a, *pa; + + i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); + if(i != 0) g_error("duplicate entry in attribute table"); + + a.name = name; + a.is_named = 0; a.type = t; a.value = init_value(t); g_array_append_val(self->attributes, a); @@ -161,6 +194,10 @@ lttv_attribute_remove(LttvAttribute *self, unsigned i) a = &g_array_index(self->attributes, Attribute, i); + /* If the element is a gobject, unreference it. */ + if(a->type == LTTV_GOBJECT && a->value.dv_gobject != NULL) + g_object_unref(a->value.dv_gobject); + /* Remove the array element and its entry in the name index */ g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name)); @@ -169,7 +206,7 @@ lttv_attribute_remove(LttvAttribute *self, unsigned i) /* The element used to replace the removed element has its index entry all wrong now. Reinsert it with its new position. */ - if(self->attributes->len != i){ + if(likely(self->attributes->len != i)){ g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name)); g_hash_table_insert(self->names, GUINT_TO_POINTER(a->name), GUINT_TO_POINTER(i + 1)); } @@ -181,7 +218,7 @@ lttv_attribute_remove_by_name(LttvAttribute *self, LttvAttributeName name) unsigned i; i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); - if(i == 0) g_error("remove by name non existent attribute"); + if(unlikely(i == 0)) g_error("remove by name non existent attribute"); lttv_attribute_remove(self, i - 1); } @@ -199,11 +236,11 @@ lttv_attribute_find_subdir(LttvAttribute *self, LttvAttributeName name) Attribute a; LttvAttribute *new; - + i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); - if(i != 0) { + if(likely(i != 0)) { a = g_array_index(self->attributes, Attribute, i - 1); - if(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject)) { + if(likely(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject))) { return LTTV_ATTRIBUTE(a.value.dv_gobject); } else return NULL; @@ -213,6 +250,29 @@ lttv_attribute_find_subdir(LttvAttribute *self, LttvAttributeName name) return (LttvAttribute *)new; } +/*CHECK*/LttvAttribute* +lttv_attribute_find_subdir_unnamed(LttvAttribute *self, LttvAttributeName name) +{ + unsigned i; + + Attribute a; + + LttvAttribute *new; + + i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); + if(likely(i != 0)) { + a = g_array_index(self->attributes, Attribute, i - 1); + if(likely(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject))) { + return LTTV_ATTRIBUTE(a.value.dv_gobject); + } + else return NULL; + } + new = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); + *(lttv_attribute_add_unnamed(self, name, LTTV_GOBJECT).v_gobject) + = G_OBJECT(new); + return (LttvAttribute *)new; +} + gboolean lttv_attribute_find(LttvAttribute *self, LttvAttributeName name, LttvAttributeType t, LttvAttributeValue *v) @@ -222,9 +282,9 @@ lttv_attribute_find(LttvAttribute *self, LttvAttributeName name, Attribute *a; i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); - if(i != 0) { + if(likely(i != 0)) { a = &g_array_index(self->attributes, Attribute, i - 1); - if(a->type != t) return FALSE; + if(unlikely(a->type != t)) return FALSE; *v = address_of_value(t, &(a->value)); return TRUE; } @@ -233,8 +293,28 @@ lttv_attribute_find(LttvAttribute *self, LttvAttributeName name, return TRUE; } +gboolean +lttv_attribute_find_unnamed(LttvAttribute *self, LttvAttributeName name, + LttvAttributeType t, LttvAttributeValue *v) +{ + unsigned i; + + Attribute *a; + + i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); + if(likely(i != 0)) { + a = &g_array_index(self->attributes, Attribute, i - 1); + if(unlikely(a->type != t)) return FALSE; + *v = address_of_value(t, &(a->value)); + return TRUE; + } + + *v = lttv_attribute_add_unnamed(self, name, t); + return TRUE; +} + -void lttv_attribute_recursive_free(LttvAttribute *self) +/*void lttv_attribute_recursive_free(LttvAttribute *self) { int i, nb; @@ -249,7 +329,7 @@ void lttv_attribute_recursive_free(LttvAttribute *self) } } g_object_unref(self); -} +}*/ void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src) @@ -265,14 +345,22 @@ void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src) for(i = 0 ; i < nb ; i++) { a = &g_array_index(src->attributes, Attribute, i); if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) { - lttv_attribute_recursive_add( - /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir(dest, a->name), - (LttvAttribute *)(a->value.dv_gobject)); + if(a->is_named) + lttv_attribute_recursive_add( + /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir(dest, a->name), + (LttvAttribute *)(a->value.dv_gobject)); + else + lttv_attribute_recursive_add( + /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir_unnamed( + dest, a->name), (LttvAttribute *)(a->value.dv_gobject)); } else { - g_assert(lttv_attribute_find(dest, a->name, a->type, &value)); + if(a->is_named) + g_assert(lttv_attribute_find(dest, a->name, a->type, &value)); + else + g_assert(lttv_attribute_find_unnamed(dest, a->name, a->type, &value)); switch(a->type) { - case LTTV_INT: + case LTTV_INT: *value.v_int += a->value.dv_int; break; case LTTV_UINT: @@ -329,7 +417,7 @@ lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent) for(i = 0 ; i < nb ; i++) { a = &g_array_index(self->attributes, Attribute, i); print_indent(fp, pos); - fprintf(fp, "name); + fprintf(fp, "name)); if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) { fprintf(fp, "TYPE=ATTRS>"); lttv_attribute_write_xml((LttvAttribute *)(a->value.dv_gobject), fp, @@ -356,7 +444,7 @@ lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent) fprintf(fp, "TYPE=DOUBLE VALUE=%f/>\n", a->value.dv_double); break; case LTTV_TIME: - fprintf(fp, "TYPE=TIME SEC=%u NSEC=%u/>\n", a->value.dv_time.tv_sec, + fprintf(fp, "TYPE=TIME SEC=%lu NSEC=%lu/>\n", a->value.dv_time.tv_sec, a->value.dv_time.tv_nsec); break; case LTTV_POINTER: @@ -382,9 +470,7 @@ lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent) void lttv_attribute_read_xml(LttvAttribute *self, FILE *fp) { - int i, nb, res; - - Attribute *a; + int res; char buffer[256], type[10]; @@ -433,12 +519,12 @@ lttv_attribute_read_xml(LttvAttribute *self, FILE *fp) } else if(strcmp(type, "DOUBLE") == 0) { value = lttv_attribute_add(self, name, LTTV_DOUBLE); - res = fscanf(fp, " VALUE=%f/>", value.v_double); + res = fscanf(fp, " VALUE=%lf/>", value.v_double); g_assert(res == 1); } else if(strcmp(type, "TIME") == 0) { value = lttv_attribute_add(self, name, LTTV_TIME); - res = fscanf(fp, " SEC=%u NSEC=%u/>", &(value.v_time->tv_sec), + res = fscanf(fp, " SEC=%lu NSEC=%lu/>", &(value.v_time->tv_sec), &(value.v_time->tv_nsec)); g_assert(res == 2); } @@ -467,12 +553,21 @@ lttv_attribute_read_xml(LttvAttribute *self, FILE *fp) fscanf(fp,""); } +static LttvAttribute * +new_attribute (LttvAttribute *self) +{ + return g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); +} + static void attribute_interface_init (gpointer g_iface, gpointer iface_data) { LttvIAttributeClass *klass = (LttvIAttributeClass *)g_iface; + klass->new_attribute = (LttvIAttribute* (*) (LttvIAttribute *self)) + new_attribute; + klass->get_number = (unsigned int (*) (LttvIAttribute *self)) lttv_attribute_get_number; @@ -480,7 +575,8 @@ attribute_interface_init (gpointer g_iface, gpointer iface_data) lttv_attribute_named; klass->get = (LttvAttributeType (*) (LttvIAttribute *self, unsigned i, - LttvAttributeName *name, LttvAttributeValue *v)) lttv_attribute_get; + LttvAttributeName *name, LttvAttributeValue *v, gboolean *is_named)) + lttv_attribute_get; klass->get_by_name = (LttvAttributeType (*) (LttvIAttribute *self, LttvAttributeName name, LttvAttributeValue *v)) @@ -489,6 +585,9 @@ attribute_interface_init (gpointer g_iface, gpointer iface_data) klass->add = (LttvAttributeValue (*) (LttvIAttribute *self, LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add; + klass->add_unnamed = (LttvAttributeValue (*) (LttvIAttribute *self, + LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add_unnamed; + klass->remove = (void (*) (LttvIAttribute *self, unsigned i)) lttv_attribute_remove; @@ -497,14 +596,17 @@ attribute_interface_init (gpointer g_iface, gpointer iface_data) klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self, LttvAttributeName name)) lttv_attribute_find_subdir; -} + klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self, + LttvAttributeName name)) lttv_attribute_find_subdir_unnamed; +} static void attribute_instance_init (GTypeInstance *instance, gpointer g_class) { LttvAttribute *self = (LttvAttribute *)instance; - self->names = g_hash_table_new(g_direct_hash, g_direct_equal); + self->names = g_hash_table_new(g_direct_hash, + g_direct_equal); self->attributes = g_array_new(FALSE, FALSE, sizeof(Attribute)); } @@ -512,11 +614,15 @@ attribute_instance_init (GTypeInstance *instance, gpointer g_class) static void attribute_finalize (LttvAttribute *self) { - g_hash_table_destroy(self->names); + guint i; g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "attribute_finalize()"); + + for(i=0;iattributes->len;i++) { + lttv_attribute_remove(self, i); + } + + g_hash_table_destroy(self->names); g_array_free(self->attributes, TRUE); - G_OBJECT_CLASS(g_type_class_peek_parent( - g_type_class_peek(LTTV_ATTRIBUTE_TYPE)))->finalize(G_OBJECT(self)); } @@ -524,7 +630,7 @@ static void attribute_class_init (LttvAttributeClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - + gobject_class->finalize = (void (*)(GObject *self))attribute_finalize; } @@ -542,7 +648,8 @@ lttv_attribute_get_type (void) NULL, /* class_data */ sizeof (LttvAttribute), 0, /* n_preallocs */ - (GInstanceInitFunc) attribute_instance_init /* instance_init */ + (GInstanceInitFunc) attribute_instance_init, /* instance_init */ + NULL /* value handling */ }; static const GInterfaceInfo iattribute_info = {