]> git.sur5r.net Git - openldap/commitdiff
Keep some dn2i/id2e cursors open longer
authorHoward Chu <hyc@openldap.org>
Fri, 7 Oct 2011 02:14:22 +0000 (19:14 -0700)
committerHoward Chu <hyc@openldap.org>
Fri, 7 Oct 2011 02:14:22 +0000 (19:14 -0700)
So they can be reused, and avoid unnecessary page_searches

servers/slapd/back-mdb/dn2id.c
servers/slapd/back-mdb/id2entry.c
servers/slapd/back-mdb/nextid.c

index 5431226ae43b26bce9c7b403a0fae74c6f5408c5..45a36e28048d8e24b44f1cda3732759cd854a0d6 100644 (file)
@@ -136,14 +136,13 @@ int mdb_fix_dn(
 int
 mdb_dn2id_add(
        Operation       *op,
-       MDB_txn *txn,
+       MDB_cursor      *mcp,
+       MDB_cursor      *mcd,
        ID pid,
        Entry           *e )
 {
        struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
-       MDB_dbi dbi = mdb->mi_dn2id;
        MDB_val         key, data;
-       MDB_cursor      *mc;
        ID              nid;
        int             rc, rlen, nrlen;
        diskNode *d;
@@ -174,10 +173,6 @@ mdb_dn2id_add(
 
        nid = pid;
 
-       rc = mdb_cursor_open( txn, dbi, &mc );
-       if ( rc )
-               goto fail;
-
        /* Need to make dummy root node once. Subsequent attempts
         * will fail harmlessly.
         */
@@ -186,22 +181,21 @@ mdb_dn2id_add(
                data.mv_data = &dummy;
                data.mv_size = sizeof(diskNode);
 
-               mdb_cursor_put( mc, &key, &data, MDB_NODUPDATA );
+               mdb_cursor_put( mcp, &key, &data, MDB_NODUPDATA );
        }
 
        data.mv_data = d;
        data.mv_size = sizeof(diskNode) + rlen + nrlen;
 
-       rc = mdb_cursor_put( mc, &key, &data, MDB_NODUPDATA );
+       rc = mdb_cursor_put( mcp, &key, &data, MDB_NODUPDATA );
 
        if (rc == 0) {
                nid = e->e_id;
                memcpy( ptr, &pid, sizeof( ID ));
                d->nrdnlen[0] ^= 0x80;
 
-               rc = mdb_cursor_put( mc, &key, &data, MDB_NODUPDATA|MDB_APPEND );
+               rc = mdb_cursor_put( mcd, &key, &data, MDB_NODUPDATA|MDB_APPEND );
        }
-       mdb_cursor_close( mc );
 
 fail:
        op->o_tmpfree( d, op->o_tmpmemctx );
@@ -210,61 +204,47 @@ fail:
        return rc;
 }
 
+/* mc must have been set by mdb_dn2id */
 int
 mdb_dn2id_delete(
        Operation       *op,
-       MDB_txn *txn,
-       ID pid,
-       Entry   *e )
+       MDB_cursor *mc,
+       ID id )
 {
-       struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
-       MDB_dbi dbi = mdb->mi_dn2id;
-       MDB_val key, data;
-       diskNode *d;
-       int rc, nrlen;
-       ID      nid;
-
-       Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2id_delete 0x%lx: \"%s\"\n",
-               e->e_id, e->e_ndn, 0 );
-
-       key.mv_size = sizeof(ID);
-       key.mv_data = &nid;
-       nid = pid;
-
-       nrlen = dn_rdnlen( op->o_bd, &e->e_nname );
-       data.mv_size = sizeof(diskNode) + nrlen - sizeof(ID) - 1;
+       int rc;
 
-       d = op->o_tmpalloc( data.mv_size, op->o_tmpmemctx );
-       d->nrdnlen[1] = nrlen & 0xff;
-       d->nrdnlen[0] = (nrlen >> 8) | 0x80;
-       memcpy( d->nrdn, e->e_nname.bv_val, nrlen );
-       d->nrdn[nrlen] = '\0';
-       data.mv_data = d;
+       Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2id_delete 0x%lx\n",
+               id, 0, 0 );
 
        /* Delete our ID from the parent's list */
-       rc = mdb_del( txn, dbi, &key, &data );
+       rc = mdb_cursor_del( mc, 0 );
 
        /* Delete our ID from the tree. With sorted duplicates, this
         * will leave any child nodes still hanging around. This is OK
         * for modrdn, which will add our info back in later.
         */
        if ( rc == 0 ) {
-               nid = e->e_id;
-               d->nrdnlen[0] ^= 0x80;
-               rc = mdb_del( txn, dbi, &key, &data );
+               MDB_val key;
+               key.mv_size = sizeof(ID);
+               key.mv_data = &id;
+               rc = mdb_cursor_get( mc, &key, NULL, MDB_SET );
+               if ( rc == 0 )
+                       rc = mdb_cursor_del( mc, 0 );
        }
 
-       op->o_tmpfree( d, op->o_tmpmemctx );
-
-       Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id_delete 0x%lx: %d\n", e->e_id, rc, 0 );
+       Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id_delete 0x%lx: %d\n", id, rc, 0 );
        return rc;
 }
 
-/* return last found ID in *id if no match */
+/* return last found ID in *id if no match
+ * If mc is provided, it will be left pointing to the RDN's
+ * record under the parent's ID.
+ */
 int
 mdb_dn2id(
        Operation       *op,
        MDB_txn *txn,
+       MDB_cursor      *mc,
        struct berval   *in,
        ID      *id,
        struct berval   *matched,
@@ -316,8 +296,12 @@ mdb_dn2id(
        nid = 0;
        key.mv_size = sizeof(ID);
 
-       rc = mdb_cursor_open( txn, dbi, &cursor );
-       if ( rc ) return rc;
+       if ( mc ) {
+               cursor = mc;
+       } else {
+               rc = mdb_cursor_open( txn, dbi, &cursor );
+               if ( rc ) return rc;
+       }
 
        for (;;) {
                key.mv_data = &pid;
@@ -367,7 +351,8 @@ mdb_dn2id(
                }
        }
        *id = nid; 
-       mdb_cursor_close( cursor );
+       if ( !mc )
+               mdb_cursor_close( cursor );
 done:
        if ( matched ) {
                if ( matched->bv_len ) {
index afa7539fdda503ea60731c501472d8298fb55c22..d2f1715477feebb58ad161afec0bd55b6934f7c2 100644 (file)
@@ -31,18 +31,18 @@ typedef struct Ecount {
 
 static int mdb_entry_partsize(struct mdb_info *mdb, MDB_txn *txn, Entry *e,
        Ecount *eh);
-static int mdb_entry_encode(Operation *op, MDB_txn *txn, Entry *e, MDB_val *data,
+static int mdb_entry_encode(Operation *op, Entry *e, MDB_val *data,
        Ecount *ec);
 static Entry *mdb_entry_alloc( Operation *op, int nattrs, int nvals );
 
 static int mdb_id2entry_put(
        Operation *op,
-       MDB_txn *tid,
+       MDB_txn *txn,
+       MDB_cursor *mc,
        Entry *e,
        int flag )
 {
        struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
-       MDB_dbi dbi = mdb->mi_id2entry;
        Ecount ec;
        MDB_val key, data;
        int rc;
@@ -52,7 +52,7 @@ static int mdb_id2entry_put(
        key.mv_data = &e->e_id;
        key.mv_size = sizeof(ID);
 
-       rc = mdb_entry_partsize( mdb, tid, e, &ec );
+       rc = mdb_entry_partsize( mdb, txn, e, &ec );
        if (rc)
                return LDAP_OTHER;
 
@@ -60,9 +60,12 @@ static int mdb_id2entry_put(
 
 again:
        data.mv_size = ec.len;
-       rc = mdb_put( tid, dbi, &key, &data, flag );
+       if ( mc )
+               rc = mdb_cursor_put( mc, &key, &data, flag );
+       else
+               rc = mdb_put( txn, mdb->mi_id2entry, &key, &data, flag );
        if (rc == MDB_SUCCESS) {
-               rc = mdb_entry_encode( op, tid, e, &data, &ec );
+               rc = mdb_entry_encode( op, e, &data, &ec );
                if( rc != LDAP_SUCCESS )
                        return LDAP_OTHER;
        }
@@ -76,7 +79,8 @@ again:
                        "mdb_id2entry_put: mdb_put failed: %s(%d) \"%s\"\n",
                        mdb_strerror(rc), rc,
                        e->e_nname.bv_val );
-               rc = LDAP_OTHER;
+               if ( rc != MDB_KEYEXIST )
+                       rc = LDAP_OTHER;
        }
        return rc;
 }
@@ -89,18 +93,20 @@ again:
 
 int mdb_id2entry_add(
        Operation *op,
-       MDB_txn *tid,
+       MDB_txn *txn,
+       MDB_cursor *mc,
        Entry *e )
 {
-       return mdb_id2entry_put(op, tid, e, MDB_NOOVERWRITE|MDB_APPEND);
+       return mdb_id2entry_put(op, txn, mc, e, MDB_NOOVERWRITE|MDB_APPEND);
 }
 
 int mdb_id2entry_update(
        Operation *op,
-       MDB_txn *tid,
+       MDB_txn *txn,
+       MDB_cursor *mc,
        Entry *e )
 {
-       return mdb_id2entry_put(op, tid, e, 0);
+       return mdb_id2entry_put(op, txn, mc, e, 0);
 }
 
 int mdb_id2entry(
@@ -289,7 +295,7 @@ int mdb_entry_get(
        txn = moi->moi_txn;
 
        /* can we find entry */
-       rc = mdb_dn2entry( op, txn, ndn, &e, 0 );
+       rc = mdb_dn2entry( op, txn, NULL, ndn, &e, 0 );
        switch( rc ) {
        case MDB_NOTFOUND:
        case 0:
@@ -537,7 +543,7 @@ static int mdb_entry_partsize(struct mdb_info *mdb, MDB_txn *txn, Entry *e,
  * The entire buffer size is precomputed so that a single malloc can be
  * performed.
  */
-static int mdb_entry_encode(Operation *op, MDB_txn *txn, Entry *e, MDB_val *data, Ecount *eh)
+static int mdb_entry_encode(Operation *op, Entry *e, MDB_val *data, Ecount *eh)
 {
        struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
        ber_len_t len, i;
index 1d7b3893cb0d3c431154a5cea08cb866ee943eb4..d6c5d945765ff5b31c7a7c067d7d494caa8e5ff6 100644 (file)
 
 #include "back-mdb.h"
 
-int mdb_next_id( BackendDB *be, MDB_txn *tid, ID *out )
+int mdb_next_id( BackendDB *be, MDB_cursor *mc, ID *out )
 {
-       struct mdb_info *mdb = (struct mdb_info *) be->be_private;
        int rc;
        ID id = 0;
        MDB_val key;
-       MDB_cursor *cursor;
 
-       /* Get a read cursor */
-       rc = mdb_cursor_open( tid, mdb->mi_id2entry, &cursor );
-
-       if (rc == 0) {
-               rc = mdb_cursor_get(cursor, &key, NULL, MDB_LAST);
-               mdb_cursor_close(cursor);
-       }
+       rc = mdb_cursor_get(mc, &key, NULL, MDB_LAST);
 
        switch(rc) {
        case MDB_NOTFOUND: