From b79d63516dc6fea57f3364307e576c9203038f21 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Thu, 30 Nov 2006 06:03:56 +0000 Subject: [PATCH] Rewrite attrs_dup with attrs_alloc. Add new entry_dup_bv that dups an entry in a single malloc. Leave it unused for now; faster but consumes more heap. --- servers/slapd/attr.c | 46 +++++++++++++----------- servers/slapd/entry.c | 73 ++++++++++++++++++++++++++++++++++++++ servers/slapd/proto-slap.h | 1 + 3 files changed, 100 insertions(+), 20 deletions(-) diff --git a/servers/slapd/attr.c b/servers/slapd/attr.c index 4c21b9bfc0..82c94abaa0 100644 --- a/servers/slapd/attr.c +++ b/servers/slapd/attr.c @@ -181,15 +181,10 @@ attrs_free( Attribute *a ) } } -Attribute * -attr_dup( Attribute *a ) -{ - Attribute *tmp; - - if ( a == NULL) return NULL; - - tmp = attr_alloc( a->a_desc ); +static void +attr_dup2( Attribute *tmp, Attribute *a ) +{ if ( a->a_vals != NULL ) { int i; @@ -224,31 +219,42 @@ attr_dup( Attribute *a ) } else { tmp->a_nvals = tmp->a_vals; } - - } else { - tmp->a_vals = NULL; - tmp->a_nvals = NULL; } +} + +Attribute * +attr_dup( Attribute *a ) +{ + Attribute *tmp; + + if ( a == NULL) return NULL; + + tmp = attr_alloc( a->a_desc ); + attr_dup2( tmp, a ); return tmp; } Attribute * attrs_dup( Attribute *a ) { - Attribute *tmp, **next; + int i; + Attribute *tmp, *anew; if( a == NULL ) return NULL; - tmp = NULL; - next = &tmp; + /* count them */ + for( tmp=a,i=0; tmp; tmp=tmp->a_next ) { + i++; + } + + anew = attrs_alloc( i ); - for( ; a != NULL ; a = a->a_next ) { - *next = attr_dup( a ); - next = &((*next)->a_next); + for( tmp=anew; a; a=a->a_next ) { + attr_dup2( tmp, a ); + tmp=tmp->a_next; } - *next = NULL; - return tmp; + return anew; } diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index e7c4222b7d..f074fb6549 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -862,3 +862,76 @@ Entry *entry_dup( Entry *e ) return ret; } +#if 1 +/* Duplicates an entry using a single malloc. Saves CPU time, increases + * heap usage because a single large malloc is harder to satisfy than + * lots of small ones, and the freed space isn't as easily reusable. + * + * Probably not worth using this function. + */ +Entry *entry_dup_bv( Entry *e ) +{ + ber_len_t len; + int nattrs, nvals; + Entry *ret; + struct berval *bvl; + char *ptr; + Attribute *src, *dst; + + ret = entry_alloc(); + + entry_partsize(e, &len, &nattrs, &nvals, 1); + ret->e_id = e->e_id; + ret->e_attrs = attrs_alloc( nattrs ); + ret->e_ocflags = e->e_ocflags; + ret->e_bv.bv_len = len + nvals * sizeof(struct berval); + ret->e_bv.bv_val = ch_malloc( ret->e_bv.bv_len ); + + bvl = (struct berval *)ret->e_bv.bv_val; + ptr = (char *)(bvl + nvals); + + ret->e_name.bv_len = e->e_name.bv_len; + ret->e_name.bv_val = ptr; + AC_MEMCPY( ptr, e->e_name.bv_val, e->e_name.bv_len ); + ptr += e->e_name.bv_len; + *ptr++ = '\0'; + + ret->e_nname.bv_len = e->e_nname.bv_len; + ret->e_nname.bv_val = ptr; + AC_MEMCPY( ptr, e->e_nname.bv_val, e->e_nname.bv_len ); + ptr += e->e_name.bv_len; + *ptr++ = '\0'; + + dst = ret->e_attrs; + for (src = e->e_attrs; src; src=src->a_next,dst=dst->a_next ) { + int i; + dst->a_desc = src->a_desc; + dst->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS; + dst->a_vals = bvl; + for ( i=0; src->a_vals[i].bv_val; i++ ) { + bvl->bv_len = src->a_vals[i].bv_len; + bvl->bv_val = ptr; + AC_MEMCPY( ptr, src->a_vals[i].bv_val, bvl->bv_len ); + ptr += bvl->bv_len; + *ptr++ = '\0'; + bvl++; + } + BER_BVZERO(bvl); + bvl++; + if ( src->a_vals != src->a_nvals ) { + dst->a_nvals = bvl; + for ( i=0; src->a_nvals[i].bv_val; i++ ) { + bvl->bv_len = src->a_nvals[i].bv_len; + bvl->bv_val = ptr; + AC_MEMCPY( ptr, src->a_nvals[i].bv_val, bvl->bv_len ); + ptr += bvl->bv_len; + *ptr++ = '\0'; + bvl++; + } + BER_BVZERO(bvl); + bvl++; + } + } + return ret; +} +#endif diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 5a8e0dc2d9..5f8b8743ad 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -872,6 +872,7 @@ LDAP_SLAPD_F (int) entry_cmp LDAP_P(( Entry *a, Entry *b )); LDAP_SLAPD_F (int) entry_dn_cmp LDAP_P(( const void *v_a, const void *v_b )); LDAP_SLAPD_F (int) entry_id_cmp LDAP_P(( const void *v_a, const void *v_b )); LDAP_SLAPD_F (Entry *) entry_dup LDAP_P(( Entry *e )); +LDAP_SLAPD_F (Entry *) entry_dup_bv LDAP_P(( Entry *e )); LDAP_SLAPD_F (Entry *) entry_alloc LDAP_P((void)); LDAP_SLAPD_F (int) entry_prealloc LDAP_P((int num)); -- 2.47.2