* MA 02111-1307, USA.
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <string.h>
#include <lttv/attribute.h>
#include <ltt/ltt.h>
+#include <ltt/compiler.h>
typedef union _AttributeValue {
int dv_int;
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;
return self->attributes->len;
}
-
gboolean
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;
}
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);
/* 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));
}
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);
}
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;
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)
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;
}
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)
{
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:
*value.v_int += a->value.dv_int;
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))
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;
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));
}