+2004-11-07 Martin Quinson
+ - Speed up dynar lookup operation a bit.
+
+ gras_dynar_get is dead.
+
+ Now, you can choose between gras_dynar_get_cpy (the old gras_dynar_get
+ but should be avoided for efficiency reasons) and gras_dynar_get_ptr
+ (which gives you the address of the stored data).
+
+ gras_dynar_get_as is an helpful macro which allows you to retrieve a
+ copy of the data using an affectation to do the job and not a memcpy.
+
+ int toto = gras_dynar_get_as(dyn,0,int); rewrites itself to
+ int toto = *(int*)gras_dynar_get_ptr(dyn,0);
+
+ It does not really speedup the dynar test because they are
+ setting elements all the time (and look them seldom). But the dict does
+ far more lookup than setting.
+
+ So, this brings the dict_crash test from ~33s to ~25s (200000 elms).
+
2004-11-04 Martin Quinson
- Allow to (en/dis)able the cycle detection at run time.
#We need a recent ACI
ACI_PREREQ(2003.01.16)
-AC_INIT([GRAS],[0.6.3],[martin.quinson@ens-lyon.fr])
+AC_INIT([GRAS],[0.7],[martin.quinson@ens-lyon.fr])
AC_CONFIG_SRCDIR([include/gras.h])
AC_CONFIG_HEADERS([src/gras_config.h])
/* regular array functions */
-void gras_dynar_get(const gras_dynar_t *dynar, int idx, void *const dst);
+void gras_dynar_get_cpy(const gras_dynar_t *dynar, int idx, void *const dst);
+void *gras_dynar_get_ptr(const gras_dynar_t * const dynar,
+ const int idx);
+
+#define gras_dynar_get_as(dynar,idx,type) *(type*)gras_dynar_get_ptr(dynar,idx)
+
void gras_dynar_set(gras_dynar_t *dynar, int idx, const void *src);
void gras_dynar_remplace(gras_dynar_t *dynar,
int idx, const void *object);
while (l--) {
char *_name = NULL;
- gras_dynar_get(frame, l, &_name);
+ _name = gras_dynar_get_as(frame, l, char*);
if (!strcmp(name, _name)) {
gras_dynar_remove_at(frame, l, &_name);
gras_free(_name);
}
gras_dynar_foreach(d1->category.struct_data.fields, cpt, field1) {
- gras_dynar_get(d2->category.struct_data.fields, cpt, &field2);
+ field2 = gras_dynar_get_as(d2->category.struct_data.fields, cpt, gras_dd_cat_field_t *);
field_desc_1 = field1->type;
field_desc_2 = field2->type;
ret = gras_datadesc_type_cmp(field_desc_1,field_desc_2);
gras_dynar_foreach(d1->category.union_data.fields, cpt, field1) {
- gras_dynar_get(d2->category.union_data.fields, cpt, field2);
+ field2 = gras_dynar_get_as(d2->category.union_data.fields, cpt, gras_dd_cat_field_t *);
field_desc_1 = field1->type;
field_desc_2 = field2->type;
ret = gras_datadesc_type_cmp(field_desc_1,field_desc_2);
TRY(gras_dd_send_int(sock, field_num));
/* Send the content */
- gras_dynar_get(union_data.fields, field_num, field);
+ field = gras_dynar_get_as(union_data.fields, field_num, gras_dd_cat_field_t *);
sub_type = field->type;
if (field->pre)
type->name, field_num, gras_dynar_length(union_data.fields));
/* Recv the content */
- gras_dynar_get(union_data.fields, field_num, field);
+ field = gras_dynar_get_as(union_data.fields, field_num, gras_dd_cat_field_t *);
sub_type = field->type;
TRY(gras_datadesc_recv_rec(sock,state,refs, sub_type,
int ival;
char *sval;
double dval;
- gras_host_t hval;
+ gras_host_t *hval;
if (name)
printf("%s>> Dumping of the config set '%s':\n",indent,name);
case gras_cfgelm_int:
for (i=0; i<size; i++) {
- gras_dynar_get(cell->content,i,&ival);
+ ival = gras_dynar_get_as(cell->content,i,int);
printf ("%s %d\n",indent,ival);
}
break;
case gras_cfgelm_double:
for (i=0; i<size; i++) {
- gras_dynar_get(cell->content,i,&dval);
+ dval = gras_dynar_get_as(cell->content,i,double);
printf ("%s %f\n",indent,dval);
}
break;
case gras_cfgelm_string:
for (i=0; i<size; i++) {
- gras_dynar_get(cell->content,i,&sval);
+ sval = gras_dynar_get_as(cell->content,i,char*);
printf ("%s %s\n",indent,sval);
}
break;
case gras_cfgelm_host:
for (i=0; i<size; i++) {
- gras_dynar_get(cell->content,i,&hval);
- printf ("%s %s:%d\n",indent,hval.name,hval.port);
+ hval = gras_dynar_get_as(cell->content,i,gras_host_t*);
+ printf ("%s %s:%d\n",indent,hval->name,hval->port);
}
break;
name, gras_dynar_length(cell->content));
}
- gras_dynar_get(cell->content, 0, (void*)val);
+ *val = gras_dynar_get_as(cell->content, 0, int);
return no_error;
}
name, gras_dynar_length(cell->content));
}
- gras_dynar_get(cell->content, 0, (void*)val);
+ *val = gras_dynar_get_as(cell->content, 0, double);
return no_error;
}
name, gras_dynar_length(cell->content));
}
- gras_dynar_get(cell->content, 0, (void*)val);
+ *val = gras_dynar_get_as(cell->content, 0, char *);
return no_error;
}
name, gras_dynar_length(cell->content));
}
- gras_dynar_get(cell->content, 0, (void*)val);
+ val = gras_dynar_get_as(cell->content, 0, gras_host_t*);
*host=val->name;
*port=val->port;
return FALSE;
}
- gras_dynar_get((*cursor)->keys, (*cursor)->pos, key );
- gras_dynar_get((*cursor)->key_lens, (*cursor)->pos_len, &key_len);
+ *key = gras_dynar_get_as((*cursor)->keys, (*cursor)->pos, char*);
+ key_len = gras_dynar_get_as((*cursor)->key_lens, (*cursor)->pos_len, int);
errcode = gras_dictelm_get_ext((*cursor)->head, *key, key_len, data);
if (errcode == mismatch_error) {
TRY(__cursor_not_null(p_cursor));
- gras_dynar_get(p_cursor->keys, p_cursor->pos - 1, key);
+ *key = gras_dynar_get_as(p_cursor->keys, p_cursor->pos - 1, char*);
return errcode;
}
TRY(__cursor_not_null(p_cursor));
- gras_dynar_get(p_cursor->keys, p_cursor->pos-1, &key );
- gras_dynar_get(p_cursor->key_lens, p_cursor->pos_len-1, &key_len);
+ key = gras_dynar_get_as(p_cursor->keys, p_cursor->pos-1, char *);
+ key_len = gras_dynar_get_as(p_cursor->key_lens, p_cursor->pos_len-1, int);
TRY(gras_dictelm_get_ext(p_cursor->head, key, key_len, data));
int o = *p_offset;
int m = *p_match;
- gras_dynar_get(p_dict->sub, pos, &p_child);
+ p_child = gras_dynar_get_as(p_dict->sub, pos, gras_dictelm_t*);
/* Compute the length of the prefix
and if the searched key is before or after cur */
{
gras_dictelm_t *p_child = NULL;
- gras_dynar_get(p_head->sub, pos, &p_child);
+ p_child = gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
CDEBUG1(dict_add, "-> Change the value of the child %p", (void*)p_child);
_gras_dictelm_change_value(p_child, data, free_ctn);
{
gras_dictelm_t *p_child = NULL;
- gras_dynar_get(p_head->sub, pos, &p_child);
+ p_child=gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
CDEBUG2(dict_add,"-> Recurse on %p (offset=%d)", (void*)p_child, offset);
_gras_dictelm_set_rec(p_child, key, key_len,
gras_dictelm_t *p_new = NULL;
gras_dictelm_t *p_child = NULL;
- gras_dynar_get(p_head->sub, pos, &p_child);
+ p_child=gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
_gras_dictelm_alloc(key, key_len, old_offset, data, free_ctn, &p_new);
CDEBUG2(dict_add, "-> The child %p become child of new dict (%p)",
int anc_key_len = offset;
_gras_dictelm_alloc(key, key_len, offset, data, free_ctn, &p_new);
- gras_dynar_get(p_head->sub, pos, &p_child);
+ p_child=gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
anc_key = gras_memdup(key, anc_key_len);
{
gras_dictelm_t *p_child = NULL;
- gras_dynar_get(p_head->sub, pos, &p_child);
+ p_child = gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
*data = p_child->content;
return no_error;
{
gras_dictelm_t *p_child = NULL;
- gras_dynar_get(p_head->sub, pos, &p_child);
+ p_child = gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
return _gras_dictelm_get_rec(p_child, key, key_len, offset, data);
}
if (pos >= 0) {
/* Remove the child if |it's key| == 0 (meaning it's dead) */
- gras_dynar_get(p_head->sub, pos, &p_child);
+ p_child = gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
if (offset >= p_child->key_len) {
return; /* cannot collapse */
}
- gras_dynar_get(p_head->sub, 0, &p_child);
+ p_child = gras_dynar_get_as(p_head->sub, 0, gras_dictelm_t*);
/* Get the child's key as new key */
CDEBUG2(dict_collapse,
{
gras_dictelm_t *p_child = NULL;
- gras_dynar_get(p_head->sub, pos, &p_child);
+ p_child = gras_dynar_get_as(p_head->sub, pos, gras_dictelm_t*);
/*DEBUG5("Recurse on child %d of %p to remove %.*s (prefix=%d)",
pos, (void*)p_child, key+offset, key_len-offset,offset);*/
TRY(_gras_dictelm_remove_rec(p_child, key, key_len, offset));
static _GRAS_INLINE
void *
_gras_dynar_elm(const gras_dynar_t * const dynar,
- const unsigned long idx) {
+ const unsigned long idx) {
char * const data = dynar->data;
const unsigned long elmsize = dynar->elmsize;
return (dynar ? (unsigned long) dynar->used : (unsigned long)0);
}
+/**
+ * gras_dynar_get_cpy:
+ * @dynar: information dealer
+ * @idx: index of the slot we want to retrive
+ * @dst: where to pu the result to.
+ *
+ * Retrieve a copy of the Nth element of a dynar.
+ */
+void
+gras_dynar_get_cpy(const gras_dynar_t * const dynar,
+ const int idx,
+ void * const dst) {
+
+ __sanity_check_dynar(dynar);
+ __sanity_check_idx(idx);
+ __check_inbound_idx(dynar, idx);
+
+ _gras_dynar_get_elm(dst, dynar, idx);
+}
+
/**
* gras_dynar_get:
* @dynar: information dealer
* Retrieve the Nth element of a dynar. Warning, the returned value is the actual content of
* the dynar. Make a copy before fooling with it.
*/
-void
-gras_dynar_get(const gras_dynar_t * const dynar,
- const int idx,
- void * const dst) {
+void*
+gras_dynar_get_ptr(const gras_dynar_t * const dynar,
+ const int idx) {
__sanity_check_dynar(dynar);
__sanity_check_idx(idx);
__check_inbound_idx(dynar, idx);
- _gras_dynar_get_elm(dst, dynar, idx);
+ return _gras_dynar_elm(dynar, idx);
}
/**
/* Don't bother checking the bounds, the dynar does so */
- gras_dynar_get(set->dynar,id,dst);
+ *dst = gras_dynar_get_as(set->dynar,id,gras_set_elm_t *);
DEBUG3("Lookup type of id %d (of %lu): %s",
id, gras_dynar_length(set->dynar), (*dst)->name);
MAINTAINERCLEANFILES=Makefile.in
EXTRA_DIST=run_tests.in \
gras/datadesc.little32 gras/datadesc.little64 gras/datadesc.big32 gras/datadesc.big64 \
+ gras/datadesc.aix \
gras/mk_datadesc_structs.pl
# Test stuff
xbt/config_usage \
\
gras/trp_tcp_usage gras/trp_file_usage \
- gras/datadesc_usage
-# "gras/datadesc_usage --read @srcdir@/datadesc.little32" \
-# "gras/datadesc_usage --read @srcdir@/datadesc.big32" \
-# "gras/datadesc_usage --read @srcdir@/datadesc.big64"
-
-# "gras/datadesc_usage --read @srcdir@/datadesc.little64" \
+ gras/datadesc_usage \
+ "gras/datadesc_usage --read @srcdir@/gras/datadesc.little32" \
+ "gras/datadesc_usage --read @srcdir@/gras/datadesc.little64" \
+ "gras/datadesc_usage --read @srcdir@/gras/datadesc.big32" \
+ "gras/datadesc_usage --read @srcdir@/gras/datadesc.big64" \
+ "gras/datadesc_usage --read @srcdir@/gras/datadesc.aix"
do
tests_nb=`expr $tests_nb + 1`
echo "#### Test $test"
#include <stdio.h>
#include <stdlib.h>
-#define NB_ELM 20000
+#define NB_ELM 200000
#define SIZEOFKEY 1024
static void print_str(void *str);
gras_dynar_t *d;
gras_error_t errcode;
int i,cpt,cursor;
+ int *iptr;
gras_init_defaultlog(&argc,argv,"dynar.thresh=debug");
DEBUG2("Push %d, length=%lu",cpt, gras_dynar_length(d));
}
for (cursor=0; cursor< NB_ELEM; cursor++) {
- gras_dynar_get(d,cursor,&cpt);
- gras_assert2(cursor == cpt,
+ iptr=gras_dynar_get_ptr(d,cursor);
+ gras_assert2(cursor == *iptr,
"The retrieved value is not the same than the injected one (%d!=%d)",
cursor,cpt);
}