mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
Keep some dn2i/id2e cursors open longer
So they can be reused, and avoid unnecessary page_searches
This commit is contained in:
parent
7592013f59
commit
4c17f31843
@ -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 ) {
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user