Keep some dn2i/id2e cursors open longer

So they can be reused, and avoid unnecessary page_searches
This commit is contained in:
Howard Chu 2011-10-06 19:14:22 -07:00
parent 7592013f59
commit 4c17f31843
3 changed files with 53 additions and 70 deletions

View 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;
int rc;
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;
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 ) {

View 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;

View File

@ -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: