mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
Cursor updates
This commit is contained in:
parent
221be39208
commit
7afc68c0ec
@ -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 );
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user