diff --git a/servers/slapd/back-mdb/dn2id.c b/servers/slapd/back-mdb/dn2id.c index c0ae1781e2..c3961a26e2 100644 --- a/servers/slapd/back-mdb/dn2id.c +++ b/servers/slapd/back-mdb/dn2id.c @@ -143,6 +143,7 @@ mdb_dn2id_add( 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; @@ -173,6 +174,10 @@ 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. */ @@ -181,22 +186,24 @@ mdb_dn2id_add( data.mv_data = &dummy; data.mv_size = sizeof(diskNode); - mdb_put( txn, dbi, &key, &data, MDB_NODUPDATA ); + mdb_cursor_put( mc, &key, &data, MDB_NODUPDATA ); } data.mv_data = d; data.mv_size = sizeof(diskNode) + rlen + nrlen; - rc = mdb_put( txn, dbi, &key, &data, MDB_NODUPDATA ); + rc = mdb_cursor_put( mc, &key, &data, MDB_NODUPDATA ); if (rc == 0) { nid = e->e_id; memcpy( ptr, &pid, sizeof( ID )); d->nrdnlen[0] ^= 0x80; - rc = mdb_put( txn, dbi, &key, &data, MDB_NODUPDATA ); + rc = mdb_cursor_put( mc, &key, &data, MDB_NODUPDATA ); } + mdb_cursor_close( mc ); +fail: op->o_tmpfree( d, op->o_tmpmemctx ); Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id_add 0x%lx: %d\n", e->e_id, rc, 0 ); diff --git a/servers/slapd/back-mdb/idl.c b/servers/slapd/back-mdb/idl.c index 53d130b705..4aa7f5843c 100644 --- a/servers/slapd/back-mdb/idl.c +++ b/servers/slapd/back-mdb/idl.c @@ -391,38 +391,30 @@ mdb_idl_fetch_key( } int -mdb_idl_insert_key( - BackendDB *be, - MDB_txn *txn, - MDB_dbi dbi, +mdb_idl_insert_keys( + MDB_cursor *cursor, MDB_val *key, ID id ) { - MDB_cursor *cursor; MDB_val data; ID lo, hi, *i; char *err; - int rc; + int rc, k; { char buf[16]; Debug( LDAP_DEBUG_ARGS, - "mdb_idl_insert_key: %lx %s\n", + "mdb_idl_insert_keys: %lx %s\n", (long) id, mdb_show_key( key, buf ), 0 ); } assert( id != NOID ); - rc = mdb_cursor_open( txn, dbi, &cursor ); - if ( rc != 0 ) { - Debug( LDAP_DEBUG_ANY, "=> mdb_idl_insert_key: " - "cursor failed: %s (%d)\n", mdb_strerror(rc), rc, 0 ); - return rc; - } + for ( k=0; key[k].mv_data; k++ ) { /* Fetch the first data item for this key, to see if it * exists and if it's a range. */ - rc = mdb_cursor_get( cursor, key, &data, MDB_SET ); + rc = mdb_cursor_get( cursor, &key[k], &data, MDB_SET ); err = "c_get"; if ( rc == 0 ) { i = data.mv_data; @@ -437,28 +429,12 @@ mdb_idl_insert_key( } if ( count >= MDB_IDL_DB_MAX ) { /* No room, convert to a range */ - MDB_val key2; - lo = *i; - rc = mdb_cursor_get( cursor, &key2, &data, MDB_NEXT_NODUP ); + rc = mdb_cursor_get( cursor, &key[k], &data, MDB_LAST_DUP ); if ( rc != 0 && rc != MDB_NOTFOUND ) { - err = "c_get next_nodup"; + err = "c_get last_dup"; goto fail; } - key2 = *key; - if ( rc == MDB_NOTFOUND ) { - rc = mdb_cursor_get( cursor, &key2, &data, MDB_LAST ); - if ( rc != 0 ) { - err = "c_get last"; - goto fail; - } - } else { - rc = mdb_cursor_get( cursor, &key2, &data, MDB_PREV ); - if ( rc != 0 ) { - err = "c_get prev"; - goto fail; - } - } i = data.mv_data; hi = *i; /* Update hi/lo if needed */ @@ -468,30 +444,30 @@ mdb_idl_insert_key( hi = id; } /* delete the old key */ - rc = mdb_del( txn, dbi, &key2, NULL ); + rc = mdb_cursor_del( cursor, MDB_NODUPDATA ); if ( rc != 0 ) { - err = "mdb_del"; + err = "c_del dups"; goto fail; } /* Store the range */ data.mv_size = sizeof(ID); data.mv_data = &id; id = 0; - rc = mdb_put( txn, dbi, key, &data, 0 ); + rc = mdb_cursor_put( cursor, &key[k], &data, 0 ); if ( rc != 0 ) { - err = "mdb_put range"; + err = "c_put range"; goto fail; } id = lo; - rc = mdb_put( txn, dbi, key, &data, 0 ); + rc = mdb_cursor_put( cursor, &key[k], &data, 0 ); if ( rc != 0 ) { - err = "mdb_put lo"; + err = "c_put lo"; goto fail; } id = hi; - rc = mdb_put( txn, dbi, key, &data, 0 ); + rc = mdb_cursor_put( cursor, &key[k], &data, 0 ); if ( rc != 0 ) { - err = "mdb_put hi"; + err = "c_put hi"; goto fail; } } else { @@ -505,71 +481,65 @@ mdb_idl_insert_key( lo = i[1]; hi = i[2]; if ( id < lo || id > hi ) { - if ( id < lo ) - data.mv_data = &lo; - else - data.mv_data = &hi; + /* position on lo */ + rc = mdb_cursor_get( cursor, &key[k], &data, MDB_NEXT_DUP ); + if ( id > hi ) { + /* position on hi */ + rc = mdb_cursor_get( cursor, &key[k], &data, MDB_NEXT_DUP ); + } data.mv_size = sizeof(ID); - /* Delete the current lo/hi */ - rc = mdb_del( txn, dbi, key, &data ); + data.mv_data = &id; + /* Replace the current lo/hi */ + rc = mdb_cursor_put( cursor, &key[k], &data, MDB_CURRENT ); if ( rc != 0 ) { - err = "mdb_del lo/hi"; + err = "c_put lo/hi"; goto fail; } - goto put1; } } } else if ( rc == MDB_NOTFOUND ) { put1: data.mv_data = &id; data.mv_size = sizeof(ID); - rc = mdb_put( txn, dbi, key, &data, MDB_NODUPDATA ); + rc = mdb_cursor_put( cursor, &key[k], &data, MDB_NODUPDATA ); /* Don't worry if it's already there */ if ( rc != 0 && rc != MDB_KEYEXIST ) { - err = "mdb_put id"; + err = "c_put id"; goto fail; } } else { /* initial c_get failed, nothing was done */ fail: - Debug( LDAP_DEBUG_ANY, "=> mdb_idl_insert_key: " + Debug( LDAP_DEBUG_ANY, "=> mdb_idl_insert_keys: " "%s failed: %s (%d)\n", err, mdb_strerror(rc), rc ); } - mdb_cursor_close( cursor ); + } return rc; } int -mdb_idl_delete_key( - BackendDB *be, - MDB_txn *txn, - MDB_dbi dbi, +mdb_idl_delete_keys( + MDB_cursor *cursor, MDB_val *key, ID id ) { - int rc; + int rc, k; MDB_val data; - MDB_cursor *cursor; ID lo, hi, tmp, *i; char *err; { char buf[16]; Debug( LDAP_DEBUG_ARGS, - "mdb_idl_delete_key: %lx %s\n", + "mdb_idl_delete_keys: %lx %s\n", (long) id, mdb_show_key( key, buf ), 0 ); } assert( id != NOID ); - rc = mdb_cursor_open( txn, dbi, &cursor ); - if ( rc != 0 ) { - Debug( LDAP_DEBUG_ANY, "=> mdb_idl_delete_key: " - "cursor failed: %s (%d)\n", mdb_strerror(rc), rc, 0 ); - return rc; - } + for ( k=0; key[k].mv_data; k++) { /* Fetch the first data item for this key, to see if it * exists and if it's a range. */ - rc = mdb_cursor_get( cursor, key, &data, MDB_SET ); + rc = mdb_cursor_get( cursor, &key[k], &data, MDB_SET ); err = "c_get"; if ( rc == 0 ) { memcpy( &tmp, data.mv_data, sizeof(ID) ); @@ -577,9 +547,14 @@ mdb_idl_delete_key( if ( tmp != 0 ) { /* Not a range, just delete it */ data.mv_data = &id; - rc = mdb_del( txn, dbi, key, &data ); + rc = mdb_cursor_get( cursor, &key[k], &data, MDB_GET_BOTH ); if ( rc != 0 ) { - err = "mdb_del id"; + err = "c_get id"; + goto fail; + } + rc = mdb_cursor_del( cursor, 0 ); + if ( rc != 0 ) { + err = "c_del id"; goto fail; } } else { @@ -597,29 +572,26 @@ mdb_idl_delete_key( } if ( lo2 >= hi2 ) { /* The range has collapsed... */ - rc = mdb_del( txn, dbi, key, NULL ); + rc = mdb_cursor_del( cursor, MDB_NODUPDATA ); if ( rc != 0 ) { - err = "mdb_del"; + err = "c_del dup"; goto fail; } } else { - data.mv_size = sizeof(ID); - if ( id == lo ) - data.mv_data = &lo; - else - data.mv_data = &hi; - rc = mdb_del( txn, dbi, key, &data ); - if ( rc != 0 ) { - err = "c_del"; - goto fail; - } + /* position on lo */ + rc = mdb_cursor_get( cursor, &key[k], &data, MDB_NEXT_DUP ); if ( id == lo ) data.mv_data = &lo2; - else + else { + /* position on hi */ + rc = mdb_cursor_get( cursor, &key[k], &data, MDB_NEXT_DUP ); data.mv_data = &hi2; - rc = mdb_put( txn, dbi, key, &data, 0 ); + } + /* Replace the current lo/hi */ + data.mv_size = sizeof(ID); + rc = mdb_cursor_put( cursor, &key[k], &data, MDB_CURRENT ); if ( rc != 0 ) { - err = "mdb_put lo/hi"; + err = "c_put lo/hi"; goto fail; } } @@ -633,7 +605,7 @@ fail: "%s failed: %s (%d)\n", err, mdb_strerror(rc), rc ); } } - mdb_cursor_close( cursor ); + } return rc; } diff --git a/servers/slapd/back-mdb/index.c b/servers/slapd/back-mdb/index.c index 15057333df..78429622a1 100644 --- a/servers/slapd/back-mdb/index.c +++ b/servers/slapd/back-mdb/index.c @@ -26,7 +26,7 @@ #include "lutil_hash.h" static char presence_keyval[] = {0,0}; -static struct berval presence_key = BER_BVC(presence_keyval); +static struct berval presence_key[2] = {BER_BVC(presence_keyval), BER_BVNULL}; AttrInfo *mdb_index_mask( Backend *be, @@ -114,7 +114,7 @@ int mdb_index_param( case LDAP_FILTER_PRESENT: type = SLAP_INDEX_PRESENT; if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) { - *prefixp = presence_key; + *prefixp = presence_key[0]; goto done; } break; @@ -174,11 +174,21 @@ static int indexer( { int rc, i; struct berval *keys; + MDB_cursor *mc; + mdb_idl_keyfunc *keyfunc; assert( mask != 0 ); + rc = mdb_cursor_open( txn, dbi, &mc ); + if ( rc ) goto done; + + if ( opid == SLAP_INDEX_ADD_OP ) + keyfunc = mdb_idl_insert_keys; + else + keyfunc = mdb_idl_delete_keys; + if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) { - rc = mdb_key_change( op->o_bd, txn, dbi, &presence_key, id, opid ); + rc = keyfunc( mc, (MDB_val *)presence_key, id ); if( rc ) { goto done; } @@ -193,14 +203,11 @@ static int indexer( atname, vals, &keys, op->o_tmpmemctx ); if( rc == LDAP_SUCCESS && keys != NULL ) { - for( i=0; keys[i].bv_val != NULL; i++ ) { - rc = mdb_key_change( op->o_bd, txn, dbi, &keys[i], id, opid ); - if( rc ) { - ber_bvarray_free_x( keys, op->o_tmpmemctx ); - goto done; - } - } + rc = keyfunc( mc, (MDB_val *)keys, id ); ber_bvarray_free_x( keys, op->o_tmpmemctx ); + if ( rc ) { + goto done; + } } rc = LDAP_SUCCESS; } @@ -214,14 +221,11 @@ static int indexer( atname, vals, &keys, op->o_tmpmemctx ); if( rc == LDAP_SUCCESS && keys != NULL ) { - for( i=0; keys[i].bv_val != NULL; i++ ) { - rc = mdb_key_change( op->o_bd, txn, dbi, &keys[i], id, opid ); - if( rc ) { - ber_bvarray_free_x( keys, op->o_tmpmemctx ); - goto done; - } - } + rc = keyfunc( mc, (MDB_val *)keys, id ); ber_bvarray_free_x( keys, op->o_tmpmemctx ); + if ( rc ) { + goto done; + } } rc = LDAP_SUCCESS; @@ -236,20 +240,18 @@ static int indexer( atname, vals, &keys, op->o_tmpmemctx ); if( rc == LDAP_SUCCESS && keys != NULL ) { - for( i=0; keys[i].bv_val != NULL; i++ ) { - rc = mdb_key_change( op->o_bd, txn, dbi, &keys[i], id, opid ); - if( rc ) { - ber_bvarray_free_x( keys, op->o_tmpmemctx ); - goto done; - } - } + rc = keyfunc( mc, (MDB_val *)keys, id ); ber_bvarray_free_x( keys, op->o_tmpmemctx ); + if( rc ) { + goto done; + } } rc = LDAP_SUCCESS; } done: + mdb_cursor_close( mc ); switch( rc ) { /* The callers all know how to deal with these results */ case 0: diff --git a/servers/slapd/back-mdb/key.c b/servers/slapd/back-mdb/key.c index e33392008c..45af1cd1f4 100644 --- a/servers/slapd/back-mdb/key.c +++ b/servers/slapd/back-mdb/key.c @@ -57,38 +57,3 @@ mdb_key_read( return rc; } - -/* Add or remove stuff from index files */ -int -mdb_key_change( - Backend *be, - MDB_txn *txn, - MDB_dbi dbi, - struct berval *k, - ID id, - int op -) -{ - int rc; - MDB_val key; - - Debug( LDAP_DEBUG_TRACE, "=> key_change(%s,%lx)\n", - op == SLAP_INDEX_ADD_OP ? "ADD":"DELETE", (long) id, 0 ); - - key.mv_size = k->bv_len; - key.mv_data = k->bv_val; - - if (op == SLAP_INDEX_ADD_OP) { - /* Add values */ - rc = mdb_idl_insert_key( be, txn, dbi, &key, id ); - if ( rc == MDB_KEYEXIST ) rc = 0; - } else { - /* Delete values */ - rc = mdb_idl_delete_key( be, txn, dbi, &key, id ); - if ( rc == MDB_NOTFOUND ) rc = 0; - } - - Debug( LDAP_DEBUG_TRACE, "<= key_change %d\n", rc, 0, 0 ); - - return rc; -} diff --git a/servers/slapd/back-mdb/proto-mdb.h b/servers/slapd/back-mdb/proto-mdb.h index 2c05d6b370..7a48979bd2 100644 --- a/servers/slapd/back-mdb/proto-mdb.h +++ b/servers/slapd/back-mdb/proto-mdb.h @@ -195,19 +195,13 @@ int mdb_idl_fetch_key( int mdb_idl_insert( ID *ids, ID id ); -int mdb_idl_insert_key( - BackendDB *be, - MDB_txn *txn, - MDB_dbi dbi, +typedef int (mdb_idl_keyfunc)( + MDB_cursor *mc, MDB_val *key, ID id ); -int mdb_idl_delete_key( - BackendDB *be, - MDB_txn *txn, - MDB_dbi dbi, - MDB_val *key, - ID id ); +mdb_idl_keyfunc mdb_idl_insert_keys; +mdb_idl_keyfunc mdb_idl_delete_keys; int mdb_idl_intersection( @@ -292,15 +286,6 @@ mdb_key_read( MDB_cursor **saved_cursor, int get_flags ); -extern int -mdb_key_change( - Backend *be, - MDB_txn *txn, - MDB_dbi dbi, - struct berval *k, - ID id, - int op ); - /* * nextid.c */