X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fentry.c;h=f074fb654964d1e699336fbd0a31e604f53e5f75;hb=5747896ba081ff998fd97863de26d2f4af59bbd2;hp=f7a1fb7b8d1a320ec153f93cc437c51976f052a6;hpb=3a83c813df79e3934fe42ae0d1d2fa42a5bd7ebf;p=openldap diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index f7a1fb7b8d..f074fb6549 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -86,8 +86,8 @@ int entry_destroy(void) return attr_destroy(); } - -int entry_init(void) +int +entry_init(void) { ldap_pvt_thread_mutex_init( &entry2str_mutex ); ldap_pvt_thread_mutex_init( &entry_mutex ); @@ -456,10 +456,6 @@ entry_clean( Entry *e ) free( e->e_bv.bv_val ); } - if ( &e->e_abv ) { - free( e->e_abv ); - } - /* free attributes */ attrs_free( e->e_attrs ); @@ -720,20 +716,39 @@ int entry_encode(Entry *e, struct berval *bv) } /* Retrieve an Entry that was stored using entry_encode above. - * We malloc a single block with the size stored above for the Entry - * and all of its Attributes. We also must lookup the stored - * attribute names to get AttributeDescriptions. To detect if the - * attributes of an Entry are later modified, we note that e->e_attr - * is always a constant offset from (e). + * First entry_header must be called to decode the size of the entry. + * Then a single block of memory must be malloc'd to accomodate the + * bervals and the bulk data. Next the bulk data is retrieved from + * the DB and parsed by entry_decode. * * Note: everything is stored in a single contiguous block, so * you can not free individual attributes or names from this * structure. Attempting to do so will likely corrupt memory. */ +int entry_header(EntryHeader *eh) +{ + unsigned char *ptr = (unsigned char *)eh->bv.bv_val; + + eh->nattrs = entry_getlen(&ptr); + if ( !eh->nattrs ) { + Debug( LDAP_DEBUG_ANY, + "entry_header: attribute count was zero\n", 0, 0, 0); + return LDAP_OTHER; + } + eh->nvals = entry_getlen(&ptr); + if ( !eh->nvals ) { + Debug( LDAP_DEBUG_ANY, + "entry_header: value count was zero\n", 0, 0, 0); + return LDAP_OTHER; + } + eh->data = (char *)ptr; + return LDAP_SUCCESS; +} + #ifdef SLAP_ZONE_ALLOC -int entry_decode(struct berval *bv, Entry **e, void *ctx) +int entry_decode(EntryHeader *eh, Entry **e, void *ctx) #else -int entry_decode(struct berval *bv, Entry **e) +int entry_decode(EntryHeader *eh, Entry **e) #endif { int i, j, count, nattrs, nvals; @@ -742,24 +757,14 @@ int entry_decode(struct berval *bv, Entry **e) Entry *x; const char *text; AttributeDescription *ad; - unsigned char *ptr = (unsigned char *)bv->bv_val; + unsigned char *ptr = (unsigned char *)eh->bv.bv_val; BerVarray bptr; - nattrs = entry_getlen(&ptr); - if (!nattrs) { - Debug( LDAP_DEBUG_ANY, - "entry_decode: attribute count was zero\n", 0, 0, 0); - return LDAP_OTHER; - } - nvals = entry_getlen(&ptr); - if (!nvals) { - Debug( LDAP_DEBUG_ANY, - "entry_decode: value count was zero\n", 0, 0, 0); - return LDAP_OTHER; - } + nattrs = eh->nattrs; + nvals = eh->nvals; x = entry_alloc(); x->e_attrs = attrs_alloc( nattrs ); - x->e_abv = ch_malloc( nvals * sizeof( struct berval )); + ptr = (unsigned char *)eh->data; i = entry_getlen(&ptr); x->e_name.bv_val = (char *) ptr; x->e_name.bv_len = i; @@ -771,10 +776,10 @@ int entry_decode(struct berval *bv, Entry **e) Debug( LDAP_DEBUG_TRACE, "entry_decode: \"%s\"\n", x->e_dn, 0, 0 ); - x->e_bv = *bv; + x->e_bv = eh->bv; a = x->e_attrs; - bptr = x->e_abv; + bptr = (BerVarray)eh->bv.bv_val; while ((i = entry_getlen(&ptr))) { struct berval bv; @@ -853,10 +858,80 @@ Entry *entry_dup( Entry *e ) ber_dupbv( &ret->e_nname, &e->e_nname ); ret->e_attrs = attrs_dup( e->e_attrs ); ret->e_ocflags = e->e_ocflags; - ret->e_bv.bv_val = NULL; - ret->e_bv.bv_len = 0; - ret->e_private = NULL; 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