]> git.sur5r.net Git - openldap/commitdiff
Entry/Attribute struct caching, to minimize malloc fragmentation
authorHoward Chu <hyc@openldap.org>
Tue, 29 Aug 2006 01:43:23 +0000 (01:43 +0000)
committerHoward Chu <hyc@openldap.org>
Tue, 29 Aug 2006 01:43:23 +0000 (01:43 +0000)
Note: this breaks LDAP_COMP_MATCH and SLAP_ZONE_MALLOC. But they
were probably broken already anyway.

26 files changed:
servers/slapd/add.c
servers/slapd/attr.c
servers/slapd/back-bdb/id2entry.c
servers/slapd/back-bdb/init.c
servers/slapd/back-ldap/search.c
servers/slapd/back-meta/search.c
servers/slapd/back-monitor/entry.c
servers/slapd/back-sql/config.c
servers/slapd/back-sql/entry-id.c
servers/slapd/back-sql/operational.c
servers/slapd/back-sql/search.c
servers/slapd/bconfig.c
servers/slapd/ctxcsn.c
servers/slapd/entry.c
servers/slapd/init.c
servers/slapd/operational.c
servers/slapd/overlays/accesslog.c
servers/slapd/overlays/syncprov.c
servers/slapd/overlays/translucent.c
servers/slapd/proto-slap.h
servers/slapd/root_dse.c
servers/slapd/schema.c
servers/slapd/slap.h
servers/slapd/slapi/slapi_utils.c
servers/slapd/syncrepl.c
servers/slapd/value.c

index 314d044aab249978f40cf5c1998a4e69337ceb27..b69f7a720dedc6c5f4893d21c83132018e30b3bd 100644 (file)
@@ -69,7 +69,7 @@ do_add( Operation *op, SlapReply *rs )
                return SLAPD_DISCONNECT;
        }
 
-       op->ora_e = (Entry *) ch_calloc( 1, sizeof(Entry) );
+       op->ora_e = entry_alloc();
 
        rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn,
                op->o_tmpmemctx );
@@ -506,10 +506,7 @@ slap_mods2entry(
                        }
                }
 
-               attr = ch_calloc( 1, sizeof(Attribute) );
-
-               /* move ad to attr structure */
-               attr->a_desc = mods->sml_desc;
+               attr = attr_alloc( mods->sml_desc );
 
                /* move values to attr structure */
                /*      should check for duplicates */
index fc9579283ae1e3083308da79145e74d5bcea8b2e..36878d2398d43f960fbde55fbbd21a255c1185bd 100644 (file)
 
 #include "slap.h"
 
+/*
+ * Allocate in chunks, minimum of 1000 at a time.
+ */
+#define        CHUNK_SIZE      1000
+typedef struct slap_list {
+       struct slap_list *next;
+} slap_list;
+static slap_list *attr_chunks;
+static Attribute *attr_list;
+static ldap_pvt_thread_mutex_t attr_mutex;
+
+int
+attr_prealloc( int num )
+{
+       Attribute *a;
+       slap_list *s;
+
+       if (!num) return 0;
+
+       s = ch_calloc( 1, sizeof(slap_list) + num * sizeof(Attribute));
+       s->next = attr_chunks;
+       attr_chunks = s;
+
+       a = (Attribute *)(s+1);
+       for ( ;num>1; num--) {
+               a->a_next = a+1;
+               a++;
+       }
+       a->a_next = attr_list;
+       attr_list = (Attribute *)(s+1);
+
+       return 0;
+}
+
 Attribute *
 attr_alloc( AttributeDescription *ad )
 {
-       Attribute *a = ch_malloc( sizeof(Attribute) );
-
-       a->a_desc = ad;
+       Attribute *a;
+       
+       
+       ldap_pvt_thread_mutex_lock( &attr_mutex );
+       if ( !attr_list )
+               attr_prealloc( CHUNK_SIZE );
+       a = attr_list;
+       attr_list = a->a_next;
        a->a_next = NULL;
-       a->a_flags = 0;
-       a->a_vals = NULL;
-       a->a_nvals = NULL;
-#ifdef LDAP_COMP_MATCH
-       a->a_comp_data = NULL;
-#endif
+       ldap_pvt_thread_mutex_unlock( &attr_mutex );
+       
+       a->a_desc = ad;
 
        return a;
 }
 
+/* Return a list of num attrs */
+Attribute *
+attrs_alloc( int num )
+{
+       Attribute *head = NULL;
+       Attribute **a;
+
+       ldap_pvt_thread_mutex_lock( &attr_mutex );
+       for ( a = &attr_list; *a && num > 0; a = &(*a)->a_next ) {
+               if ( !head )
+                       head = *a;
+               num--;
+       }
+       attr_list = *a;
+       if ( num > 0 ) {
+               attr_prealloc( num > CHUNK_SIZE ? num : CHUNK_SIZE );
+               *a = attr_list;
+               for ( ; *a && num > 0; a = &(*a)->a_next ) {
+                       if ( !head )
+                               head = *a;
+                       num--;
+               }
+               attr_list = *a;
+       }
+       *a = NULL;
+       ldap_pvt_thread_mutex_unlock( &attr_mutex );
+
+       return head;
+}
+
+
 void
 attr_free( Attribute *a )
 {
-       if ( a->a_nvals && a->a_nvals != a->a_vals ) {
-               ber_bvarray_free( a->a_nvals );
+       if ( a->a_nvals && a->a_nvals != a->a_vals &&
+               !( a->a_flags & SLAP_ATTR_DONT_FREE_VALS )) {
+               if ( a->a_flags & SLAP_ATTR_DONT_FREE_DATA ) {
+                       free( a->a_nvals );
+               } else {
+                       ber_bvarray_free( a->a_nvals );
+               }
        }
        /* a_vals may be equal to slap_dummy_bv, a static empty berval;
         * this is used as a placeholder for attributes that do not carry
         * values, e.g. when proxying search entries with the "attrsonly"
         * bit set. */
-       if ( a->a_vals != &slap_dummy_bv ) {
-               ber_bvarray_free( a->a_vals );
+       if ( a->a_vals != &slap_dummy_bv &&
+               !( a->a_flags & SLAP_ATTR_DONT_FREE_VALS )) {
+               if ( a->a_flags & SLAP_ATTR_DONT_FREE_DATA ) {
+                       free( a->a_vals );
+               } else {
+                       ber_bvarray_free( a->a_vals );
+               }
        }
-       free( a );
+       memset( a, 0, sizeof( Attribute ));
+       ldap_pvt_thread_mutex_lock( &attr_mutex );
+       a->a_next = attr_list;
+       attr_list = a;
+       ldap_pvt_thread_mutex_unlock( &attr_mutex );
 }
 
 #ifdef LDAP_COMP_MATCH
@@ -399,3 +480,22 @@ attr_delete(
        return LDAP_NO_SUCH_ATTRIBUTE;
 }
 
+int
+attr_init( void )
+{
+       ldap_pvt_thread_mutex_init( &attr_mutex );
+       return 0;
+}
+
+int
+attr_destroy( void )
+{
+       slap_list *a;
+
+       for ( a=attr_chunks; a; a=attr_chunks ) {
+               attr_chunks = a->next;
+               free( a );
+       }
+       ldap_pvt_thread_mutex_destroy( &attr_mutex );
+       return 0;
+}
index 869c217aad1899c20290640f3c02a15d792a7bf2..58fafd1cc9ba834a88123dd2eced5c078eded935 100644 (file)
@@ -176,64 +176,31 @@ int bdb_id2entry_delete(
        return rc;
 }
 
-#ifdef SLAP_ZONE_ALLOC
-int bdb_entry_return(
-       struct bdb_info *bdb,
-       Entry *e,
-       int zseq
-)
-#else
 int bdb_entry_return(
        Entry *e
 )
-#endif
 {
-#ifdef SLAP_ZONE_ALLOC
-       if (!slap_zn_validate(bdb->bi_cache.c_zctx, e, zseq)) {
-               return 0;
-       }
-#endif
        /* Our entries are allocated in two blocks; the data comes from
         * the db itself and the Entry structure and associated pointers
         * are allocated in entry_decode. The db data pointer is saved
-        * in e_bv. Since the Entry structure is allocated as a single
-        * block, e_attrs is always a fixed offset from e. The exception
-        * is when an entry has been modified, in which case we also need
-        * to free e_attrs.
+        * in e_bv.
         */
-
-#ifdef LDAP_COMP_MATCH
-       comp_tree_free( e->e_attrs );
-#endif
-       if( !e->e_bv.bv_val ) { /* Entry added by do_add */
-               entry_free( e );
-               return 0;
-       }
-       if( (void *) e->e_attrs != (void *) (e+1)) {
-               attrs_free( e->e_attrs );
-       }
-
-       /* See if the DNs were changed by modrdn */
-       if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val >
-               e->e_bv.bv_val + e->e_bv.bv_len ) {
-               ch_free(e->e_name.bv_val);
-               ch_free(e->e_nname.bv_val);
+       if ( e->e_bv.bv_val ) {
+               /* See if the DNs were changed by modrdn */
+               if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val >
+                       e->e_bv.bv_val + e->e_bv.bv_len ) {
+                       ch_free(e->e_name.bv_val);
+                       ch_free(e->e_nname.bv_val);
+               }
                e->e_name.bv_val = NULL;
                e->e_nname.bv_val = NULL;
+               /* In tool mode the e_bv buffer is realloc'd, leave it alone */
+               if( !(slapMode & SLAP_TOOL_MODE) ) {
+                       free( e->e_bv.bv_val );
+               }
+               BER_BVZERO( &e->e_bv );
        }
-#ifndef SLAP_ZONE_ALLOC
-       /* In tool mode the e_bv buffer is realloc'd, leave it alone */
-       if( !(slapMode & SLAP_TOOL_MODE) ) {
-               free( e->e_bv.bv_val );
-       }
-#endif /* !SLAP_ZONE_ALLOC */
-
-#ifdef SLAP_ZONE_ALLOC
-       slap_zn_free( e, bdb->bi_cache.c_zctx );
-#else
-       free( e );
-#endif
-
+       entry_free( e );
        return 0;
 }
 
index e8c156298102e34fa0da4889a57f6348b344a01b..dccc3290706a1e77cea20792d3712727c958cd1d 100644 (file)
@@ -424,6 +424,8 @@ bdb_db_open( BackendDB *be )
 
        bdb->bi_flags |= BDB_IS_OPEN;
 
+       entry_prealloc( bdb->bi_cache.c_maxsize );
+       attr_prealloc( bdb->bi_cache.c_maxsize * 20 );
        return 0;
 
 fail:
index 97d4ee2c7a87d6cfd5025e03a383ce0090968840..16b08fe8a388e972c4482fb67618acb2e8d6cd17 100644 (file)
@@ -565,13 +565,10 @@ ldap_build_entry(
                slap_syntax_validate_func       *validate;
                slap_syntax_transform_func      *pretty;
 
-               attr = (Attribute *)ch_malloc( sizeof( Attribute ) );
+               attr = attr_alloc( NULL );
                if ( attr == NULL ) {
                        continue;
                }
-               attr->a_flags = 0;
-               attr->a_next = 0;
-               attr->a_desc = NULL;
                if ( slap_bv2ad( &a, &attr->a_desc, &text ) 
                                != LDAP_SUCCESS )
                {
@@ -792,7 +789,7 @@ retry:
                goto cleanup;
        }
 
-       *ent = ch_calloc( 1, sizeof( Entry ) );
+       *ent = entry_alloc();
        if ( *ent == NULL ) {
                rc = LDAP_NO_MEMORY;
                goto cleanup;
index 463141d2b2edb6110dd4dd5cb3062356eaca4cc9..8bd5877f783d95a1971e9751d2e3be583e5b6250 100644 (file)
@@ -1417,7 +1417,7 @@ meta_send_entry(
                        ( void )ber_scanf( &ber, "x" /* [W] */ );
                        continue;
                }
-               attr = ( Attribute * )ch_calloc( 1, sizeof( Attribute ) );
+               attr = attr_alloc( NULL );
                if ( attr == NULL ) {
                        continue;
                }
index 3a2377489bb10613aeee8762347b30f09436b986..3b3d4691c531c8c08351d0af4991c55ff48d8f1b 100644 (file)
@@ -193,7 +193,7 @@ monitor_entry_stub(
        if ( rc )
                return NULL;
 
-       e = ch_calloc( 1, sizeof( Entry ));
+       e = entry_alloc();
        if ( e ) {
                struct berval nrdn;
 
index 817435f94c538ddce3a43db78f5553a2e5a0180e..88d02229e33bd403153884919dfd4e751d7ed05b 100644 (file)
@@ -661,10 +661,10 @@ read_baseObject(
                return LDAP_OTHER;
        }
 
-       bi->sql_baseObject = (Entry *) SLAP_CALLOC( 1, sizeof(Entry) );
+       bi->sql_baseObject = entry_alloc();
        if ( bi->sql_baseObject == NULL ) {
                Debug( LDAP_DEBUG_ANY,
-                       "read_baseObject_file: SLAP_CALLOC failed", 0, 0, 0 );
+                       "read_baseObject_file: entry_alloc failed", 0, 0, 0 );
                ldif_close( fp );
                return LDAP_NO_MEMORY;
        }
index 801729e73363a8e2d7a8ccd7aa5666949dc0655b..d381fe3a29c2ffedf9e376428bba0c9cbbd76987 100644 (file)
@@ -615,10 +615,7 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                append = 1;
 
                /* Make space for the array of values */
-               attr = (Attribute *) ch_malloc( sizeof( Attribute ) );
-               attr->a_desc = at->bam_ad;
-               attr->a_flags = 0;
-               attr->a_next = NULL;
+               attr = attr_alloc( at->bam_ad );
                attr->a_vals = ch_calloc( count + 1, sizeof( struct berval ) );
                if ( attr->a_vals == NULL ) {
                        Debug( LDAP_DEBUG_TRACE, "Out of memory!\n", 0,0,0 );
index f103939181522dd7f574ee1e43442cfcc269050c..f0933a6318edacb5a98a7ca8e5a8849179f2c924 100644 (file)
@@ -53,8 +53,7 @@ backsql_operational_entryUUID( backsql_info *bi, backsql_entryID *id )
                return NULL;
        }
 
-       a = ch_malloc( sizeof( Attribute ) );
-       a->a_desc = desc;
+       a = attr_alloc( desc );
 
        a->a_vals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
        a->a_vals[ 0 ] = val;
@@ -63,9 +62,6 @@ backsql_operational_entryUUID( backsql_info *bi, backsql_entryID *id )
        a->a_nvals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
        a->a_nvals[ 0 ] = nval;
        BER_BVZERO( &a->a_nvals[ 1 ] );
-       
-       a->a_next = NULL;
-       a->a_flags = 0;
 
        return a;
 }
@@ -77,8 +73,7 @@ backsql_operational_entryCSN( Operation *op )
        struct berval   entryCSN;
        Attribute       *a;
 
-       a = ch_malloc( sizeof( Attribute ) );
-       a->a_desc = slap_schema.si_ad_entryCSN;
+       a = attr_alloc( slap_schema.si_ad_entryCSN );
        a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
        BER_BVZERO( &a->a_vals[ 1 ] );
 
@@ -100,9 +95,6 @@ backsql_operational_entryCSN( Operation *op )
 
        a->a_nvals = a->a_vals;
 
-       a->a_next = NULL;
-       a->a_flags = 0;
-
        return a;
 }
 
index 6824827a0959af93bb4e74dfa5422469fd26857a..1e3d92d9c7fff4f286830daed7336e1b044a962e 100644 (file)
@@ -2469,7 +2469,7 @@ backsql_entry_get(
                BER_BVZERO( &anlist[ 1 ].an_name );
        }
 
-       bsi.bsi_e = ch_malloc( sizeof( Entry ) );
+       bsi.bsi_e = entry_alloc();
        rc = backsql_init_search( &bsi,
                        ndn,
                        LDAP_SCOPE_BASE, 
index ada0f53d21a1f7c406988b9525ad36cf015f81b6..351d4946f0366db25a03832cb01f3c825e27c8b7 100644 (file)
@@ -4403,7 +4403,7 @@ Entry *
 config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
        ConfigArgs *c, struct berval *rdn, ConfigOCs *main, ConfigOCs *extra )
 {
-       Entry *e = ch_calloc( 1, sizeof(Entry) );
+       Entry *e = entry_alloc();
        CfEntryInfo *ce = ch_calloc( 1, sizeof(CfEntryInfo) );
        struct berval val;
        struct berval ad_name;
index a018d471191d86b218a7540d883e340608b67f55..0cab941536b648fec82e1431db46a74c6e27c841 100644 (file)
@@ -128,7 +128,7 @@ slap_create_context_csn_entry(
 
        struct berval bv;
 
-       e = (Entry *) ch_calloc( 1, sizeof( Entry ));
+       e = entry_alloc();
 
        attr_merge( e, slap_schema.si_ad_objectClass,
                ocbva, NULL );
index 93c27985b3cf116155dfdac3c73c83ea02f1bfb9..fed66efdc9d5abb1fa23121bebad2e65eb3aee94 100644 (file)
@@ -47,18 +47,53 @@ const Entry slap_entry_root = {
        NOID, { 0, "" }, { 0, "" }, NULL, 0, { 0, "" }, NULL
 };
 
+/*
+ * these mutexes must be used when calling the entry2str()
+ * routine since it returns a pointer to static data.
+ */
+ldap_pvt_thread_mutex_t        entry2str_mutex;
+
 static const struct berval dn_bv = BER_BVC("dn");
 
+/*
+ * Entry free list
+ *
+ * Allocate in chunks, minimum of 1000 at a time.
+ */
+#define        CHUNK_SIZE      1000
+typedef struct slap_list {
+       struct slap_list *next;
+} slap_list;
+static slap_list *entry_chunks;
+static Entry *entry_list;
+static ldap_pvt_thread_mutex_t entry_mutex;
+
 int entry_destroy(void)
 {
+       slap_list *e;
        if ( ebuf ) free( ebuf );
        ebuf = NULL;
        ecur = NULL;
        emaxsize = 0;
-       return 0;
+
+       for ( e=entry_chunks; e; e=entry_chunks ) {
+               entry_chunks = e->next;
+               free( e );
+       }
+
+       ldap_pvt_thread_mutex_destroy( &entry_mutex );
+       ldap_pvt_thread_mutex_destroy( &entry2str_mutex );
+       return attr_destroy();
 }
 
 
+int entry_init(void)
+{
+       ldap_pvt_thread_mutex_init( &entry2str_mutex );
+       ldap_pvt_thread_mutex_init( &entry_mutex );
+       return attr_init();
+}
+
 Entry *
 str2entry( char *s )
 {
@@ -97,8 +132,7 @@ str2entry2( char *s, int checkvals )
        Debug( LDAP_DEBUG_TRACE, "=> str2entry: \"%s\"\n",
                s ? s : "NULL", 0, 0 );
 
-       /* initialize reader/writer lock */
-       e = (Entry *) ch_calloc( 1, sizeof(Entry) );
+       e = entry_alloc();
 
        if( e == NULL ) {
                Debug( LDAP_DEBUG_ANY,
@@ -228,7 +262,7 @@ str2entry2( char *s, int checkvals )
 
                if (( ad_prev && ad != ad_prev ) || ( i == lines )) {
                        int j, k;
-                       atail->a_next = (Attribute *) ch_malloc( sizeof(Attribute) );
+                       atail->a_next = attr_alloc( NULL );
                        atail = atail->a_next;
                        atail->a_flags = 0;
                        atail->a_desc = ad_prev;
@@ -409,26 +443,27 @@ entry_clean( Entry *e )
 
        /* e_private must be freed by the caller */
        assert( e->e_private == NULL );
-       e->e_private = NULL;
 
        /* free DNs */
        if ( !BER_BVISNULL( &e->e_name ) ) {
                free( e->e_name.bv_val );
-               BER_BVZERO( &e->e_name );
        }
        if ( !BER_BVISNULL( &e->e_nname ) ) {
                free( e->e_nname.bv_val );
-               BER_BVZERO( &e->e_nname );
        }
 
        if ( !BER_BVISNULL( &e->e_bv ) ) {
                free( e->e_bv.bv_val );
-               BER_BVZERO( &e->e_bv );
+       }
+
+       if ( &e->e_abv ) {
+               free( e->e_abv );
        }
 
        /* free attributes */
        attrs_free( e->e_attrs );
-       e->e_attrs = NULL;
+
+       memset(e, 0, sizeof(Entry));
 }
 
 void
@@ -436,9 +471,52 @@ entry_free( Entry *e )
 {
        entry_clean( e );
 
-       free( e );
+       ldap_pvt_thread_mutex_lock( &entry_mutex );
+       e->e_private = entry_list;
+       entry_list = e;
+       ldap_pvt_thread_mutex_unlock( &entry_mutex );
 }
 
+int
+entry_prealloc( int num )
+{
+       Entry *e;
+       slap_list *s;
+
+       if (!num) return 0;
+
+       s = ch_calloc( 1, sizeof(slap_list) + num * sizeof(Entry));
+       s->next = entry_chunks;
+       entry_chunks = s;
+
+       e = (Entry *)(s+1);
+       for ( ;num>1; num--) {
+               e->e_private = e+1;
+               e++;
+       }
+       e->e_private = entry_list;
+       entry_list = (Entry *)(s+1);
+
+       return 0;
+}
+
+Entry *
+entry_alloc( void )
+{
+       Entry *e;
+
+       ldap_pvt_thread_mutex_lock( &entry_mutex );
+       if ( !entry_list )
+               entry_prealloc( CHUNK_SIZE );
+       e = entry_list;
+       entry_list = e->e_private;
+       e->e_private = NULL;
+       ldap_pvt_thread_mutex_unlock( &entry_mutex );
+
+       return e;
+}
+
+
 /*
  * These routines are used only by Backend.
  *
@@ -616,8 +694,8 @@ int entry_encode(Entry *e, struct berval *bv)
                *ptr++ = '\0';
                if (a->a_vals) {
                        for (i=0; a->a_vals[i].bv_val; i++);
-                               entry_putlen(&ptr, i);
-                               for (i=0; a->a_vals[i].bv_val; i++) {
+                       entry_putlen(&ptr, i);
+                       for (i=0; a->a_vals[i].bv_val; i++) {
                                entry_putlen(&ptr, a->a_vals[i].bv_len);
                                AC_MEMCPY(ptr, a->a_vals[i].bv_val,
                                        a->a_vals[i].bv_len);
@@ -679,19 +757,9 @@ int entry_decode(struct berval *bv, Entry **e)
                        "entry_decode: value count was zero\n", 0, 0, 0);
                return LDAP_OTHER;
        }
-       i = sizeof(Entry) + (nattrs * sizeof(Attribute)) +
-               (nvals * sizeof(struct berval));
-#ifdef SLAP_ZONE_ALLOC
-       x = slap_zn_calloc(1, i + bv->bv_len, ctx);
-       AC_MEMCPY((char*)x + i, bv->bv_val, bv->bv_len);
-       bv->bv_val = (char*)x + i;
-       ptr = (unsigned char *)bv->bv_val;
-       /* pointer is reset, now advance past nattrs and nvals again */
-       entry_getlen(&ptr);
-       entry_getlen(&ptr);
-#else
-       x = ch_calloc(1, i);
-#endif
+       x = entry_alloc();
+       x->e_attrs = attrs_alloc( nattrs );
+       x->e_abv = ch_malloc( nvals * sizeof( struct berval ));
        i = entry_getlen(&ptr);
        x->e_name.bv_val = (char *) ptr;
        x->e_name.bv_len = i;
@@ -705,21 +773,13 @@ int entry_decode(struct berval *bv, Entry **e)
                x->e_dn, 0, 0 );
        x->e_bv = *bv;
 
-       /* A valid entry must have at least one attr, so this
-        * pointer can never be NULL
-        */
-       x->e_attrs = (Attribute *)(x+1);
-       bptr = (BerVarray)x->e_attrs;
-       a = NULL;
+       a = x->e_attrs;
+       bptr = x->e_abv;
 
        while ((i = entry_getlen(&ptr))) {
                struct berval bv;
                bv.bv_len = i;
                bv.bv_val = (char *) ptr;
-               if (a) {
-                       a->a_next = (Attribute *)bptr;
-               }
-               a = (Attribute *)bptr;
                ad = NULL;
                rc = slap_bv2ad( &bv, &ad, &text );
 
@@ -737,13 +797,9 @@ int entry_decode(struct berval *bv, Entry **e)
                }
                ptr += i + 1;
                a->a_desc = ad;
-               bptr = (BerVarray)(a+1);
-               a->a_vals = bptr;
-               a->a_flags = 0;
-#ifdef LDAP_COMP_MATCH
-               a->a_comp_data = NULL;
-#endif
+               a->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS;
                count = j = entry_getlen(&ptr);
+               a->a_vals = bptr;
 
                while (j) {
                        i = entry_getlen(&ptr);
@@ -774,12 +830,12 @@ int entry_decode(struct berval *bv, Entry **e)
                } else {
                        a->a_nvals = a->a_vals;
                }
+               a = a->a_next;
                nattrs--;
                if ( !nattrs )
                        break;
        }
 
-       if (a) a->a_next = NULL;
        Debug(LDAP_DEBUG_TRACE, "<= entry_decode(%s)\n",
                x->e_dn, 0, 0 );
        *e = x;
index 4476d6a40e8317b5267100ed95ed27254764877a..a69cefe73ce73c6e7b9541a0b0fc6aebee92f749 100644 (file)
@@ -71,11 +71,6 @@ ldap_pvt_thread_mutex_t      gmtime_mutex;
 
 slap_counters_t                        slap_counters;
 
-/*
- * these mutexes must be used when calling the entry2str()
- * routine since it returns a pointer to static data.
- */
-ldap_pvt_thread_mutex_t        entry2str_mutex;
 ldap_pvt_thread_mutex_t        replog_mutex;
 
 static const char* slap_name = NULL;
@@ -119,6 +114,13 @@ slap_init( int mode, const char *name )
                return 1;
        }
 
+       if ( entry_init() != 0 ) {
+               slap_debug |= LDAP_DEBUG_NONE;
+               Debug( LDAP_DEBUG_ANY,
+                   "%s: entry_init failed\n",
+                   name, 0, 0 );
+               return 1;
+       }
 
        switch ( slapMode & SLAP_MODE ) {
        case SLAP_SERVER_MODE:
@@ -134,7 +136,6 @@ slap_init( int mode, const char *name )
 
                ldap_pvt_thread_pool_init( &connection_pool,
                                connection_pool_max, 0);
-               ldap_pvt_thread_mutex_init( &entry2str_mutex );
                ldap_pvt_thread_mutex_init( &replog_mutex );
 
                ldap_pvt_thread_mutex_init( &slap_counters.sc_sent_mutex );
index 121d5938ed662764087960ad7dcf7b27c19e9c7a..2d8510614f9c6d2ea07552b23e5e72319bbecd49 100644 (file)
@@ -29,8 +29,7 @@ slap_operational_subschemaSubentry( Backend *be )
        /* The backend wants to take care of it */
        if ( be && !SLAP_FRONTEND(be) && be->be_schemadn.bv_val ) return NULL;
 
-       a = ch_malloc( sizeof( Attribute ) );
-       a->a_desc = slap_schema.si_ad_subschemaSubentry;
+       a = attr_alloc( slap_schema.si_ad_subschemaSubentry );
 
        a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
        ber_dupbv( a->a_vals, &frontendDB->be_schemadn );
@@ -42,9 +41,6 @@ slap_operational_subschemaSubentry( Backend *be )
        a->a_nvals[1].bv_len = 0;
        a->a_nvals[1].bv_val = NULL;
 
-       a->a_next = NULL;
-       a->a_flags = 0;
-
        return a;
 }
 
@@ -57,8 +53,7 @@ slap_operational_entryDN( Entry *e )
        assert( !BER_BVISNULL( &e->e_name ) );
        assert( !BER_BVISNULL( &e->e_nname ) );
 
-       a = ch_malloc( sizeof( Attribute ) );
-       a->a_desc = slap_schema.si_ad_entryDN;
+       a = attr_alloc( slap_schema.si_ad_entryDN );
 
        a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
        ber_dupbv( &a->a_vals[ 0 ], &e->e_name );
@@ -68,9 +63,6 @@ slap_operational_entryDN( Entry *e )
        ber_dupbv( &a->a_nvals[ 0 ], &e->e_nname );
        BER_BVZERO( &a->a_nvals[ 1 ] );
 
-       a->a_next = NULL;
-       a->a_flags = 0;
-
        return a;
 }
 
@@ -82,8 +74,7 @@ slap_operational_hasSubordinate( int hs )
 
        val = hs ? slap_true_bv : slap_false_bv;
 
-       a = ch_malloc( sizeof( Attribute ) );
-       a->a_desc = slap_schema.si_ad_hasSubordinates;
+       a = attr_alloc( slap_schema.si_ad_hasSubordinates );
        a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
 
        ber_dupbv( &a->a_vals[0], &val );
@@ -91,9 +82,6 @@ slap_operational_hasSubordinate( int hs )
 
        a->a_nvals = a->a_vals;
 
-       a->a_next = NULL;
-       a->a_flags = 0;
-
        return a;
 }
 
index f9f90c8255db3c5e4808fac34bc616f8c98095a2..f0a7d45d7600c6008d9b527a390eb7608eeb7548 100644 (file)
@@ -813,7 +813,7 @@ static Entry *accesslog_entry( Operation *op, int logop,
        struct berval rdn, nrdn, timestamp, ntimestamp, bv;
        slap_verbmasks *lo = logops+logop+EN_OFFSET;
 
-       Entry *e = ch_calloc( 1, sizeof(Entry) );
+       Entry *e = entry_alloc();
 
        strcpy( rdnbuf, RDNEQ );
        rdn.bv_val = rdnbuf;
@@ -1484,7 +1484,7 @@ accesslog_db_open(
                const char *text = NULL;
                Entry *e_ctx;
 
-               e = ch_calloc( 1, sizeof( Entry ));
+               e = entry_alloc();
                e->e_name = *li->li_db->be_suffix;
                e->e_nname = *li->li_db->be_nsuffix;
 
index db037774693f70488de90fee7b11bcf17ee6302a..c03f8f532cdd5dcdf8ce44a4539add64ab826ab0 100644 (file)
@@ -2132,13 +2132,10 @@ syncprov_operational(
                        if ( !a ) {
                                for ( ap = &rs->sr_operational_attrs; *ap; ap=&(*ap)->a_next );
 
-                               a = ch_malloc( sizeof(Attribute));
-                               a->a_desc = slap_schema.si_ad_contextCSN;
+                               a = attr_alloc( slap_schema.si_ad_contextCSN );
                                a->a_vals = ch_malloc( 2 * sizeof(struct berval));
                                a->a_vals[1].bv_val = NULL;
                                a->a_nvals = a->a_vals;
-                               a->a_next = NULL;
-                               a->a_flags = 0;
                                *ap = a;
                        }
 
index 0a446c83abd70a50d305f2a332d01d9ab07aae59..12a2db2211db5de86ee1596ad5e61f98a736ebcb 100644 (file)
@@ -141,13 +141,12 @@ void glue_parent(Operation *op) {
 
        Debug(LDAP_DEBUG_TRACE, "=> glue_parent: fabricating glue for <%s>\n", ndn.bv_val, 0, 0);
 
-       e = ch_calloc(1, sizeof(Entry));
+       e = entry_alloc();
        e->e_id = NOID;
        ber_dupbv(&e->e_name, &ndn);
        ber_dupbv(&e->e_nname, &ndn);
 
-       a = ch_calloc(1, sizeof(Attribute));
-       a->a_desc = slap_schema.si_ad_objectClass;
+       a = attr_alloc( slap_schema.si_ad_objectClass );
        a->a_vals = ch_malloc(sizeof(struct berval) * 3);
        ber_dupbv(&a->a_vals[0], &glue[0]);
        ber_dupbv(&a->a_vals[1], &glue[1]);
@@ -156,8 +155,7 @@ void glue_parent(Operation *op) {
        a->a_next = e->e_attrs;
        e->e_attrs = a;
 
-       a = ch_calloc(1, sizeof(Attribute));
-       a->a_desc = slap_schema.si_ad_structuralObjectClass;
+       a = attr_alloc( slap_schema.si_ad_structuralObjectClass );
        a->a_vals = ch_malloc(sizeof(struct berval) * 2);
        ber_dupbv(&a->a_vals[0], &glue[1]);
        ber_dupbv(&a->a_vals[1], &glue[2]);
@@ -199,12 +197,13 @@ BerVarray dup_bervarray(BerVarray b) {
 **     free only the Attribute*, not the contents;
 **
 */
-void free_attr_chain(Attribute *a) {
-       Attribute *ax;
-       for(; a; a = ax) {
-               ax = a->a_next;
-               ch_free(a);
+void free_attr_chain(Attribute *b) {
+       Attribute *a;
+       for(a=b; a; a=a->a_next) {
+               a->a_vals = NULL;
+               a->a_nvals = NULL;
        }
+       attrs_free( b );
        return;
 }
 
@@ -423,8 +422,7 @@ release:
                        if((m->sml_op & LDAP_MOD_OP) == LDAP_MOD_DELETE) del++;
                        continue;
                }
-               a = ch_calloc(1, sizeof(Attribute));
-               a->a_desc  = m->sml_desc;
+               a = attr_alloc( m->sml_desc );
                a->a_vals  = m->sml_values;
                a->a_nvals = m->sml_nvalues;
                a->a_next  = ax;
index 640fc982ce1b545f15184799dcfccad824928b75..b320565c9cd9f207c40a556e3ead87f7c7b26eb6 100644 (file)
@@ -248,6 +248,8 @@ LDAP_SLAPD_F (void) comp_tree_free LDAP_P(( Attribute *a ));
 #define attr_mergeit_one( e, d, v ) attr_merge_one( e, d, v, NULL /* FIXME */ )
 
 LDAP_SLAPD_F (Attribute *) attr_alloc LDAP_P(( AttributeDescription *ad ));
+LDAP_SLAPD_F (Attribute *) attrs_alloc LDAP_P(( int num ));
+LDAP_SLAPD_F (int) attr_prealloc LDAP_P(( int num ));
 LDAP_SLAPD_F (int) attr_merge LDAP_P(( Entry *e,
        AttributeDescription *desc,
        BerVarray vals,
@@ -271,6 +273,8 @@ LDAP_SLAPD_F (int) attr_delete LDAP_P((
 
 LDAP_SLAPD_F (void) attrs_free LDAP_P(( Attribute *a ));
 LDAP_SLAPD_F (Attribute *) attrs_dup LDAP_P(( Attribute *a ));
+LDAP_SLAPD_F (int) attr_init LDAP_P(( void ));
+LDAP_SLAPD_F (int) attr_destroy LDAP_P(( void ));
 
 
 /*
@@ -852,6 +856,8 @@ 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_alloc LDAP_P((void));
+LDAP_SLAPD_F (int) entry_prealloc LDAP_P((int num));
 
 /*
  * extended.c
index 38f9f670b23c86c41211f604cb645a30cfccb108..db2d83172a5fd0cd13139ebbbe738a501e784a04 100644 (file)
@@ -213,10 +213,10 @@ root_dse_info(
        AttributeDescription *ad_ref
                = slap_schema.si_ad_ref;
 
-       e = (Entry *) SLAP_CALLOC( 1, sizeof(Entry) );
+       e = entry_alloc();
        if( e == NULL ) {
                Debug( LDAP_DEBUG_ANY,
-                       "root_dse_info: SLAP_CALLOC failed", 0, 0, 0 );
+                       "root_dse_info: entry_alloc failed", 0, 0, 0 );
                return LDAP_OTHER;
        }
 
@@ -395,10 +395,10 @@ int read_root_dse_file( const char *fname )
                return EXIT_FAILURE;
        }
 
-       usr_attr = (Entry *) SLAP_CALLOC( 1, sizeof(Entry) );
+       usr_attr = entry_alloc();
        if( usr_attr == NULL ) {
                Debug( LDAP_DEBUG_ANY,
-                       "read_root_dse_file: SLAP_CALLOC failed", 0, 0, 0 );
+                       "read_root_dse_file: entry_alloc failed", 0, 0, 0 );
                ldif_close( fp );
                return LDAP_OTHER;
        }
index e78686c75847fac1f17819850275700855d3d91a..403dac0cdfa9f7adfd83f3e245f03b798f67ef01 100644 (file)
@@ -42,11 +42,11 @@ schema_info( Entry **entry, const char **text )
        struct berval   vals[5];
        struct berval   nvals[5];
 
-       e = (Entry *) SLAP_CALLOC( 1, sizeof(Entry) );
+       e = entry_alloc();
        if( e == NULL ) {
                /* Out of memory, do something about it */
                Debug( LDAP_DEBUG_ANY, 
-                       "schema_info: SLAP_CALLOC failed - out of memory.\n", 0, 0, 0 );
+                       "schema_info: entry_alloc failed - out of memory.\n", 0, 0, 0 );
                *text = "out of memory";
                return LDAP_OTHER;
        }
index 75100eb8fc9244c5c9df1a69c1cc8f8a00266e84..67dca3df488f6eb21a42b046ae31744ef3d4ddb3 100644 (file)
@@ -1102,6 +1102,8 @@ typedef struct slap_attr {
        unsigned a_flags;
 #define SLAP_ATTR_IXADD                0x1U
 #define SLAP_ATTR_IXDEL                0x2U
+#define SLAP_ATTR_DONT_FREE_DATA       0x4U
+#define SLAP_ATTR_DONT_FREE_VALS       0x8U
 } Attribute;
 
 
@@ -1134,6 +1136,7 @@ typedef struct slap_entry {
        slap_mask_t     e_ocflags;
 
        struct berval   e_bv;           /* For entry_encode/entry_decode */
+       struct berval   *e_abv;
 
        /* for use by the backend for any purpose */
        void*   e_private;
index d3fa90ab745c84f0e1290c5fece7aa6f3699eee8..3a0939ff43a16e0f9e493a8265579ec387d3c006 100644 (file)
@@ -205,7 +205,7 @@ slapi_entry_attr_delete(
 Slapi_Entry *
 slapi_entry_alloc( void ) 
 {
-       return (Slapi_Entry *)slapi_ch_calloc( 1, sizeof(Slapi_Entry) );
+       return (Slapi_Entry *)entry_alloc();
 }
 
 void 
index 1d72a0893402feed674a035693cae5fd80555942..a92e59225b953c84de4ce2c5ccec9c2728f3635e 100644 (file)
@@ -1260,7 +1260,7 @@ syncrepl_message_to_op(
                }
 
                if ( op->o_tag == LDAP_REQ_ADD ) {
-                       op->ora_e = ( Entry * ) ch_calloc( 1, sizeof( Entry ) );
+                       op->ora_e = entry_alloc();
                        op->ora_e->e_name = op->o_req_dn;
                        op->ora_e->e_nname = op->o_req_ndn;
                        rc = slap_mods2entry( modlist, &op->ora_e, 1, 0, &text, txtbuf, textlen);
@@ -1389,7 +1389,7 @@ syncrepl_message_to_entry(
                return -1;
        }
 
-       e = ( Entry * ) ch_calloc( 1, sizeof( Entry ) );
+       e = entry_alloc();
        e->e_name = op->o_req_dn;
        e->e_nname = op->o_req_ndn;
 
@@ -2179,12 +2179,11 @@ syncrepl_add_glue(
        }
 
        while ( ndn.bv_val > e->e_nname.bv_val ) {
-               glue = (Entry *) ch_calloc( 1, sizeof(Entry) );
+               glue = entry_alloc();
                ber_dupbv( &glue->e_name, &dn );
                ber_dupbv( &glue->e_nname, &ndn );
 
-               a = ch_calloc( 1, sizeof( Attribute ));
-               a->a_desc = slap_schema.si_ad_objectClass;
+               a = attr_alloc( slap_schema.si_ad_objectClass );
 
                a->a_vals = ch_calloc( 3, sizeof( struct berval ));
                ber_dupbv( &a->a_vals[0], &gcbva[0] );
@@ -2196,8 +2195,7 @@ syncrepl_add_glue(
                a->a_next = glue->e_attrs;
                glue->e_attrs = a;
 
-               a = ch_calloc( 1, sizeof( Attribute ));
-               a->a_desc = slap_schema.si_ad_structuralObjectClass;
+               a = attr_alloc( slap_schema.si_ad_structuralObjectClass );
 
                a->a_vals = ch_calloc( 2, sizeof( struct berval ));
                ber_dupbv( &a->a_vals[0], &gcbva[1] );
index f76ab54036c2df08054fd185d8892d7b771c5889..071286a0ee506f2d825d46856dcc14968f4a9332 100644 (file)
@@ -691,8 +691,7 @@ ordered_value_add(
                Attribute **ap;
                anum = 0;
                for ( ap=&e->e_attrs; *ap; ap = &(*ap)->a_next ) ;
-               a = ch_calloc( 1, sizeof(Attribute) );
-               a->a_desc = ad;
+               a = attr_alloc( ad );
                *ap = a;
        }