From 190f161d741fb87417d743b64d0100dd6e2c0855 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 13 May 2003 03:09:48 +0000 Subject: [PATCH] Optimize modify_internal, only reindex the actual modified values, not the entire attribute. --- servers/slapd/back-bdb/modify.c | 106 +++++++++++++++++++------------- 1 file changed, 63 insertions(+), 43 deletions(-) diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index 76380e9f5f..0bc2c2bb38 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -14,6 +14,9 @@ #include "back-bdb.h" #include "external.h" +#define INDEXED 0x2000 +#define NULLIFIED 0x4000 + int bdb_modify_internal( Operation *op, DB_TXN *tid, @@ -171,17 +174,6 @@ int bdb_modify_internal( if ( mod->sm_desc == slap_schema.si_ad_objectClass ) { e->e_ocflags = 0; } - - /* check if modified attribute was indexed - * but not in case of NOOP... */ - err = bdb_index_is_indexed( op->o_bd, mod->sm_desc ); - if ( err == LDAP_SUCCESS && !op->o_noop ) { - ap = attr_find( save_attrs, mod->sm_desc ); - if ( ap ) ap->a_flags |= SLAP_ATTR_IXDEL; - - ap = attr_find( e->e_attrs, mod->sm_desc ); - if ( ap ) ap->a_flags |= SLAP_ATTR_IXADD; - } } /* check that the entry still obeys the schema */ @@ -207,52 +199,80 @@ int bdb_modify_internal( } /* update the indices of the modified attributes */ + if ( !op->o_noop ) { + Modifications *m2; - /* start with deleting the old index entries */ - for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) { - if ( ap->a_flags & SLAP_ATTR_IXDEL ) { - rc = bdb_index_values( op, tid, ap->a_desc, - ap->a_nvals, - e->e_id, SLAP_INDEX_DELETE_OP ); - if ( rc != LDAP_SUCCESS ) { - attrs_free( e->e_attrs ); - e->e_attrs = save_attrs; -#ifdef NEW_LOGGING - LDAP_LOG ( OPERATION, ERR, - "bdb_modify_internal: attribute index delete failure\n", - 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "Attribute index delete failure", - 0, 0, 0 ); -#endif - return rc; + /* First look for any deletes that would nullify any adds + * in this request. I.e., deleting an entire attribute after + * assigning some values to it. + */ + for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { + if (bdb_index_is_indexed( op->o_bd, ml->sml_desc )) + continue; + switch ( ml->sml_op ) { + case LDAP_MOD_DELETE: + /* If just deleting specific values, ignore */ + if ( ml->sml_bvalues ) break; + case LDAP_MOD_REPLACE: + for ( m2 = modlist; m2 != ml; m2 = m2->sml_next ) { + if ( m2->sml_desc == ml->sml_desc && + m2->sml_op != LDAP_MOD_DELETE ) + m2->sml_op |= NULLIFIED; + } + break; } - ap->a_flags &= ~SLAP_ATTR_IXDEL; + ml->sml_op |= INDEXED; } - } - - /* add the new index entries */ - for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) { - if (ap->a_flags & SLAP_ATTR_IXADD) { - rc = bdb_index_values( op, tid, ap->a_desc, - ap->a_nvals, - e->e_id, SLAP_INDEX_ADD_OP ); + /* Now index the modifications */ + for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { + if ( ! (ml->sml_op & INDEXED) ) continue; + ml->sml_op ^= INDEXED; + switch ( ml->sml_op ) { + case LDAP_MOD_DELETE: + if ( ml->sml_bvalues ) { + rc = bdb_index_values( op, tid, ml->sml_desc, + ml->sml_nvalues ? ml->sml_nvalues : ml->sml_bvalues, + e->e_id, SLAP_INDEX_DELETE_OP ); + break; + } + /* FALLTHRU */ + case LDAP_MOD_REPLACE: + /* A nullified replace still does its delete action */ + case LDAP_MOD_REPLACE | NULLIFIED: + ap = attr_find( save_attrs, ml->sml_desc ); + rc = bdb_index_values( op, tid, ap->a_desc, + ap->a_nvals, + e->e_id, SLAP_INDEX_DELETE_OP ); + if ( rc || ml->sml_op == LDAP_MOD_DELETE || + (ml->sml_op & NULLIFIED)) + break; + /* FALLTHRU */ + case LDAP_MOD_ADD: + case SLAP_MOD_SOFTADD: + rc = bdb_index_values( op, tid, ml->sml_desc, + ml->sml_nvalues ? ml->sml_nvalues : ml->sml_bvalues, + e->e_id, SLAP_INDEX_ADD_OP ); + break; + } + ml->sml_op &= ~NULLIFIED; if ( rc != LDAP_SUCCESS ) { attrs_free( e->e_attrs ); e->e_attrs = save_attrs; #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, - "bdb_modify_internal: attribute index add failure\n", + "bdb_modify_internal: attribute index update failure\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, - "Attribute index add failure", + "Attribute index update failure", 0, 0, 0 ); #endif - return rc; + /* reset our flags */ + for (; ml; ml=ml->sml_next ) { + ml->sml_op &= ~(INDEXED | NULLIFIED); + } + break; } - ap->a_flags &= ~SLAP_ATTR_IXADD; } }