/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2011 The OpenLDAP Foundation.
+ * Copyright 2011-2013 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
ldap_pvt_thread_cond_init( &mdb_tool_index_cond_work );
if ( mdb->mi_nattrs ) {
int i;
+#if 0 /* threaded indexing has no performance advantage */
mdb_tool_threads = slap_tool_thread_max - 1;
+#endif
if ( mdb_tool_threads > 1 ) {
mdb_tool_index_rec = ch_calloc( mdb->mi_nattrs, sizeof( IndexRec ));
mdb_tool_index_tcount = mdb_tool_threads - 1;
previd = *(ID *)key.mv_data;
id = previd;
+ if ( !data.mv_size )
+ goto next;
+
if ( tool_filter || tool_base ) {
static Operation op = {0};
static Opheader ohdr = {0};
goto done;
}
}
+ if ( !data.mv_size ) {
+ rc = LDAP_NO_SUCH_OBJECT;
+ goto done;
+ }
op.o_hdr = &ohdr;
op.o_bd = be;
rc = mdb_id2name( &op, txn, &idcursor, id, &dn, &ndn );
if ( rc ) {
rc = LDAP_OTHER;
- mdb_entry_return( &op, e );
- e = NULL;
+ if ( e ) {
+ mdb_entry_return( &op, e );
+ e = NULL;
+ }
goto done;
}
if ( tool_base != NULL ) {
ch_free( dn.bv_val );
ch_free( ndn.bv_val );
rc = LDAP_NO_SUCH_OBJECT;
+ goto done;
}
}
}
mdb_tool_entry_get( BackendDB *be, ID id )
{
Entry *e = NULL;
+ int rc;
+ if ( !txn ) {
+ struct mdb_info *mdb = (struct mdb_info *) be->be_private;
+ rc = mdb_txn_begin( mdb->mi_dbenv, NULL,
+ (slapMode & SLAP_TOOL_READONLY) ? MDB_RDONLY : 0, &txn );
+ if ( rc )
+ return NULL;
+ }
+ if ( !cursor ) {
+ struct mdb_info *mdb = (struct mdb_info *) be->be_private;
+ rc = mdb_cursor_open( txn, mdb->mi_id2entry, &cursor );
+ if ( rc ) {
+ mdb_txn_abort( txn );
+ txn = NULL;
+ return NULL;
+ }
+ }
(void)mdb_tool_entry_get_int( be, id, &e );
return e;
}
text->bv_val, 0, 0 );
return NOID;
}
+ if ( !mdb->mi_nextid ) {
+ ID dummy;
+ mdb_next_id( be, idcursor, &dummy );
+ }
rc = mdb_cursor_open( txn, mdb->mi_dn2id, &mcp );
if( rc != 0 ) {
snprintf( text->bv_val, text->bv_len,
}
} else {
+ unsigned i;
mdb_txn_abort( txn );
txn = NULL;
- cursor = NULL;
+ idcursor = NULL;
+ for ( i=0; i<mdb->mi_nattrs; i++ )
+ mdb->mi_attrs[i]->ai_cursor = NULL;
+ mdb_writes = 0;
snprintf( text->bv_val, text->bv_len,
"txn_aborted! %s (%d)",
rc == LDAP_OTHER ? "Internal error" :
mi->mi_nattrs = i;
}
- if ( slapMode & SLAP_TRUNCATE_MODE ) {
- int i;
- for ( i=0; i < mi->mi_nattrs; i++ ) {
- rc = mdb_drop( txn, mi->mi_attrs[i]->ai_dbi, 0 );
- if ( rc ) {
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(mdb_tool_entry_reindex)
- ": (Truncate) mdb_drop(%s) failed: %s (%d)\n",
- mi->mi_attrs[i]->ai_desc->ad_type->sat_cname.bv_val,
- mdb_strerror(rc), rc );
- return -1;
- }
- }
- slapMode ^= SLAP_TRUNCATE_MODE;
- }
-
e = mdb_tool_entry_get( be, id );
if( e == NULL ) {
}
}
+ if ( slapMode & SLAP_TRUNCATE_MODE ) {
+ int i;
+ for ( i=0; i < mi->mi_nattrs; i++ ) {
+ rc = mdb_drop( txi, mi->mi_attrs[i]->ai_dbi, 0 );
+ if ( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ LDAP_XSTRING(mdb_tool_entry_reindex)
+ ": (Truncate) mdb_drop(%s) failed: %s (%d)\n",
+ mi->mi_attrs[i]->ai_desc->ad_type->sat_cname.bv_val,
+ mdb_strerror(rc), rc );
+ return -1;
+ }
+ }
+ slapMode ^= SLAP_TRUNCATE_MODE;
+ }
+
/*
* just (re)add them for now
- * assume that some other routine (not yet implemented)
- * will zap index databases
- *
+ * Use truncate mode to empty/reset index databases
*/
Debug( LDAP_DEBUG_TRACE,
if( rc == 0 ) {
mdb_writes++;
if ( mdb_writes >= mdb_writes_per_commit ) {
+ MDB_val key;
unsigned i;
MDB_TOOL_IDL_FLUSH( be, txi );
rc = mdb_txn_commit( txi );
+ mdb_writes = 0;
for ( i=0; i<mi->mi_nattrs; i++ )
mi->mi_attrs[i]->ai_cursor = NULL;
if( rc != 0 ) {
mdb_strerror(rc), rc, 0 );
e->e_id = NOID;
}
+ mdb_cursor_close( cursor );
txi = NULL;
+ /* Must close the read txn to allow old pages to be reclaimed. */
+ mdb_txn_abort( txn );
+ /* and then reopen it so that tool_entry_next still works. */
+ mdb_txn_begin( mi->mi_dbenv, NULL, MDB_RDONLY, &txn );
+ mdb_cursor_open( txn, mi->mi_id2entry, &cursor );
+ key.mv_data = &id;
+ key.mv_size = sizeof(ID);
+ mdb_cursor_get( cursor, &key, NULL, MDB_SET );
}
} else {
+ unsigned i;
+ mdb_writes = 0;
+ mdb_cursor_close( cursor );
+ cursor = NULL;
mdb_txn_abort( txi );
+ for ( i=0; i<mi->mi_nattrs; i++ )
+ mi->mi_attrs[i]->ai_cursor = NULL;
Debug( LDAP_DEBUG_ANY,
"=> " LDAP_XSTRING(mdb_tool_entry_reindex)
": txn_aborted! err=%d\n",
{
int rc;
struct mdb_info *mdb;
- MDB_txn *tid;
Operation op = {0};
Opheader ohdr = {0};
mdb_cursor_close( cursor );
cursor = NULL;
}
- rc = mdb_txn_begin( mdb->mi_dbenv, NULL, 0, &tid );
- if( rc != 0 ) {
- snprintf( text->bv_val, text->bv_len,
- "txn_begin failed: %s (%d)",
- mdb_strerror(rc), rc );
- Debug( LDAP_DEBUG_ANY,
- "=> " LDAP_XSTRING(mdb_tool_entry_modify) ": %s\n",
- text->bv_val, 0, 0 );
- return NOID;
+ if ( !txn ) {
+ rc = mdb_txn_begin( mdb->mi_dbenv, NULL, 0, &txn );
+ if( rc != 0 ) {
+ snprintf( text->bv_val, text->bv_len,
+ "txn_begin failed: %s (%d)",
+ mdb_strerror(rc), rc );
+ Debug( LDAP_DEBUG_ANY,
+ "=> " LDAP_XSTRING(mdb_tool_entry_modify) ": %s\n",
+ text->bv_val, 0, 0 );
+ return NOID;
+ }
}
op.o_hdr = &ohdr;
op.o_tmpmfuncs = &ch_mfuncs;
/* id2entry index */
- rc = mdb_id2entry_update( &op, tid, NULL, e );
+ rc = mdb_id2entry_update( &op, txn, NULL, e );
if( rc != 0 ) {
snprintf( text->bv_val, text->bv_len,
"id2entry_update failed: err=%d", rc );
done:
if( rc == 0 ) {
- rc = mdb_txn_commit( tid );
+ rc = mdb_txn_commit( txn );
if( rc != 0 ) {
snprintf( text->bv_val, text->bv_len,
"txn_commit failed: %s (%d)",
}
} else {
- mdb_txn_abort( tid );
+ mdb_txn_abort( txn );
snprintf( text->bv_val, text->bv_len,
"txn_aborted! %s (%d)",
mdb_strerror(rc), rc );
text->bv_val, 0, 0 );
e->e_id = NOID;
}
+ txn = NULL;
+ idcursor = NULL;
return e->e_id;
}
}
int mdb_tool_idl_add(
+ BackendDB *be,
MDB_cursor *mc,
struct berval *keys,
ID id )