From 4c17f31843d9dae3a477ca2053bbda356822ee46 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Thu, 6 Oct 2011 19:14:22 -0700 Subject: [PATCH] Keep some dn2i/id2e cursors open longer So they can be reused, and avoid unnecessary page_searches --- servers/slapd/back-mdb/dn2id.c | 79 +++++++++++++------------------ servers/slapd/back-mdb/id2entry.c | 32 ++++++++----- servers/slapd/back-mdb/nextid.c | 12 +---- 3 files changed, 53 insertions(+), 70 deletions(-) diff --git a/servers/slapd/back-mdb/dn2id.c b/servers/slapd/back-mdb/dn2id.c index 5431226ae4..45a36e2804 100644 --- a/servers/slapd/back-mdb/dn2id.c +++ b/servers/slapd/back-mdb/dn2id.c @@ -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 ) { diff --git a/servers/slapd/back-mdb/id2entry.c b/servers/slapd/back-mdb/id2entry.c index afa7539fdd..d2f1715477 100644 --- a/servers/slapd/back-mdb/id2entry.c +++ b/servers/slapd/back-mdb/id2entry.c @@ -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; diff --git a/servers/slapd/back-mdb/nextid.c b/servers/slapd/back-mdb/nextid.c index 1d7b3893cb..d6c5d94576 100644 --- a/servers/slapd/back-mdb/nextid.c +++ b/servers/slapd/back-mdb/nextid.c @@ -21,21 +21,13 @@ #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: -- 2.39.5