X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-bdb%2Findex.c;h=de4cf3d8363c3bb17e5d08da083252a18233ce3b;hb=f96e6378d6cd06c744a47af5e5e551cbb494826a;hp=4db3c6794a5fbc36b11dc965f7c6caf19b93ff96;hpb=df3d8f3e30d896499540a49c9b662155909c3aaf;p=openldap diff --git a/servers/slapd/back-bdb/index.c b/servers/slapd/back-bdb/index.c index 4db3c6794a..de4cf3d836 100644 --- a/servers/slapd/back-bdb/index.c +++ b/servers/slapd/back-bdb/index.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2000-2005 The OpenLDAP Foundation. + * Copyright 2000-2006 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,19 +28,17 @@ static char presence_keyval[LUTIL_HASH_BYTES] = {0,0,0,1}; static struct berval presence_key = {LUTIL_HASH_BYTES, presence_keyval}; -static slap_mask_t index_mask( +static AttrInfo *index_mask( Backend *be, AttributeDescription *desc, struct berval *atname ) { AttributeType *at; - slap_mask_t mask = 0; - - bdb_attr_mask( be->be_private, desc, &mask ); + AttrInfo *ai = bdb_attr_mask( be->be_private, desc ); - if( mask ) { + if( ai ) { *atname = desc->ad_cname; - return mask; + return ai; } /* If there is a tagging option, did we ever index the base @@ -48,11 +46,11 @@ static slap_mask_t index_mask( */ if( slap_ad_is_tagged( desc ) && desc != desc->ad_type->sat_ad ) { /* has tagging option */ - bdb_attr_mask( be->be_private, desc->ad_type->sat_ad, &mask ); + ai = bdb_attr_mask( be->be_private, desc->ad_type->sat_ad ); - if ( mask && ( mask ^ SLAP_INDEX_NOTAGS ) ) { + if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOTAGS ) ) { *atname = desc->ad_type->sat_cname; - return mask; + return ai; } } @@ -61,11 +59,11 @@ static slap_mask_t index_mask( /* If no AD, we've never indexed this type */ if ( !at->sat_ad ) continue; - bdb_attr_mask( be->be_private, at->sat_ad, &mask ); + ai = bdb_attr_mask( be->be_private, at->sat_ad ); - if ( mask && ( mask ^ SLAP_INDEX_NOSUBTYPES ) ) { + if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOSUBTYPES ) ) { *atname = at->sat_cname; - return mask; + return ai; } } @@ -76,18 +74,19 @@ int bdb_index_is_indexed( Backend *be, AttributeDescription *desc ) { - slap_mask_t mask; + AttrInfo *ai; struct berval prefix; - mask = index_mask( be, desc, &prefix ); + ai = index_mask( be, desc, &prefix ); - if( mask == 0 ) { + if( !ai ) return LDAP_INAPPROPRIATE_MATCHING; - } return LDAP_SUCCESS; } +/* This function is only called when evaluating search filters. + */ int bdb_index_param( Backend *be, AttributeDescription *desc, @@ -96,15 +95,17 @@ int bdb_index_param( slap_mask_t *maskp, struct berval *prefixp ) { + AttrInfo *ai; int rc; slap_mask_t mask; DB *db; - mask = index_mask( be, desc, prefixp ); + ai = index_mask( be, desc, prefixp ); - if( mask == 0 ) { + if( !ai ) { return LDAP_INAPPROPRIATE_MATCHING; } + mask = ai->ai_indexmask; rc = bdb_db_cache( be, prefixp->bv_val, &db ); @@ -169,7 +170,7 @@ static int indexer( DB *db; struct berval *keys; - assert( mask ); + assert( mask != 0 ); rc = bdb_db_cache( op->o_bd, atname->bv_val, &db ); @@ -253,6 +254,16 @@ static int indexer( } done: + switch( rc ) { + /* The callers all know how to deal with these results */ + case 0: + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + break; + /* Anything else is bad news */ + default: + rc = LDAP_OTHER; + } return rc; } @@ -268,6 +279,11 @@ static int index_at_values( { int rc; slap_mask_t mask = 0; + int ixop = opid; + AttrInfo *ai = NULL; + + if ( opid == BDB_INDEX_UPDATE_OP ) + ixop = SLAP_INDEX_ADD_OP; if( type->sat_sup ) { /* recurse */ @@ -280,49 +296,59 @@ static int index_at_values( /* If this type has no AD, we've never used it before */ if( type->sat_ad ) { + ai = bdb_attr_mask( op->o_bd->be_private, type->sat_ad ); + if ( ai ) { #ifdef LDAP_COMP_MATCH - /* component indexing */ - ComponentReference* cr_list, *cr; - - bdb_attr_mask_cr( op->o_bd->be_private, type->sat_ad, &mask, &cr_list ); - if ( cr_list ) { - for( cr = cr_list ; cr ; cr = cr->cr_next ) { - rc = indexer( op, txn, cr->cr_ad, &type->sat_cname, - cr->cr_nvals, id, opid, - cr->cr_indexmask ); + /* component indexing */ + if ( ai->ai_cr ) { + ComponentReference *cr; + for( cr = ai->ai_cr ; cr ; cr = cr->cr_next ) { + rc = indexer( op, txn, cr->cr_ad, &type->sat_cname, + cr->cr_nvals, id, ixop, + cr->cr_indexmask ); + } } - } -#else - bdb_attr_mask( op->o_bd->be_private, type->sat_ad, &mask ); #endif - ad = type->sat_ad; - } - - if( mask ) { - rc = indexer( op, txn, ad, &type->sat_cname, - vals, id, opid, - mask ); - - if( rc ) return rc; + ad = type->sat_ad; + /* If we're updating the index, just set the new bits that aren't + * already in the old mask. + */ + if ( opid == BDB_INDEX_UPDATE_OP ) + mask = ai->ai_newmask & ~ai->ai_indexmask; + else + /* For regular updates, if there is a newmask use it. Otherwise + * just use the old mask. + */ + mask = ai->ai_newmask ? ai->ai_newmask : ai->ai_indexmask; + if( mask ) { + rc = indexer( op, txn, ad, &type->sat_cname, + vals, id, ixop, mask ); + + if( rc ) return rc; + } + } } if( tags->bv_len ) { AttributeDescription *desc; - mask = 0; - desc = ad_find_tags( type, tags ); if( desc ) { - bdb_attr_mask( op->o_bd->be_private, desc, &mask ); - } - - if( mask ) { - rc = indexer( op, txn, desc, &desc->ad_cname, - vals, id, opid, - mask ); - - if( rc ) { - return rc; + ai = bdb_attr_mask( op->o_bd->be_private, desc ); + + if( ai ) { + if ( opid == BDB_INDEX_UPDATE_OP ) + mask = ai->ai_newmask & ~ai->ai_indexmask; + else + mask = ai->ai_newmask ? ai->ai_newmask : ai->ai_indexmask; + if ( mask ) { + rc = indexer( op, txn, desc, &desc->ad_cname, + vals, id, ixop, mask ); + + if( rc ) { + return rc; + } + } } } } @@ -340,6 +366,10 @@ int bdb_index_values( { int rc; + /* Never index ID 0 */ + if ( id == 0 ) + return 0; + rc = index_at_values( op, txn, desc, desc->ad_type, &desc->ad_tags, vals, id, opid ); @@ -347,6 +377,80 @@ int bdb_index_values( return rc; } +/* Get the list of which indices apply to this attr */ +int +bdb_index_recset( + struct bdb_info *bdb, + Attribute *a, + AttributeType *type, + struct berval *tags, + IndexRec *ir ) +{ + int rc, slot; + AttrList *al; + + if( type->sat_sup ) { + /* recurse */ + rc = bdb_index_recset( bdb, a, type->sat_sup, tags, ir ); + if( rc ) return rc; + } + /* If this type has no AD, we've never used it before */ + if( type->sat_ad ) { + slot = bdb_attr_slot( bdb, type->sat_ad, NULL ); + if ( slot >= 0 ) { + ir[slot].ai = bdb->bi_attrs[slot]; + al = ch_malloc( sizeof( AttrList )); + al->attr = a; + al->next = ir[slot].attrs; + ir[slot].attrs = al; + } + } + if( tags->bv_len ) { + AttributeDescription *desc; + + desc = ad_find_tags( type, tags ); + if( desc ) { + slot = bdb_attr_slot( bdb, desc, NULL ); + if ( slot >= 0 ) { + ir[slot].ai = bdb->bi_attrs[slot]; + al = ch_malloc( sizeof( AttrList )); + al->attr = a; + al->next = ir[slot].attrs; + ir[slot].attrs = al; + } + } + } + return LDAP_SUCCESS; +} + +/* Apply the indices for the recset */ +int bdb_index_recrun( + Operation *op, + struct bdb_info *bdb, + IndexRec *ir0, + ID id, + int base ) +{ + IndexRec *ir; + AttrList *al; + int i, rc = 0; + + for (i=base; ibi_nattrs; i+=slap_tool_thread_max) { + ir = ir0 + i; + if ( !ir->ai ) continue; + while (( al = ir->attrs )) { + ir->attrs = al->next; + rc = indexer( op, NULL, ir->ai->ai_desc, + &ir->ai->ai_desc->ad_type->sat_cname, + al->attr->a_nvals, id, SLAP_INDEX_ADD_OP, + ir->ai->ai_indexmask ); + free( al ); + if ( rc ) break; + } + } + return rc; +} + int bdb_index_entry( Operation *op, @@ -359,7 +463,7 @@ bdb_index_entry( #ifdef LDAP_COMP_MATCH ComponentReference *cr_list = NULL; ComponentReference *cr = NULL, *dupped_cr = NULL; - void* decoded_comp, *extracted_comp; + void* decoded_comp; ComponentSyntaxInfo* csi_attr; Syntax* syn; AttributeType* at; @@ -369,14 +473,17 @@ bdb_index_entry( #endif Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n", - opid == SLAP_INDEX_ADD_OP ? "add" : "del", + opid == SLAP_INDEX_DELETE_OP ? "del" : "add", (long) e->e_id, e->e_dn ); /* add each attribute to the indexes */ for ( ; ap != NULL; ap = ap->a_next ) { #ifdef LDAP_COMP_MATCH + AttrInfo *ai; /* see if attribute has components to be indexed */ - bdb_attr_comp_ref( op->o_bd->be_private, ap->a_desc->ad_type->sat_ad, &cr_list ); + ai = bdb_attr_mask( op->o_bd->be_private, ap->a_desc->ad_type->sat_ad ); + if ( ai ) cr_list = ai->ai_cr; + else cr_list = NULL; if ( attr_converter && cr_list ) { syn = ap->a_desc->ad_type->sat_syntax; ap->a_comp_data = op->o_tmpalloc( sizeof( ComponentData ), op->o_tmpmemctx ); @@ -439,7 +546,7 @@ bdb_index_entry( } Debug( LDAP_DEBUG_TRACE, "<= index_entry_%s( %ld, \"%s\" ) success\n", - opid == SLAP_INDEX_ADD_OP ? "add" : "del", + opid == SLAP_INDEX_DELETE_OP ? "del" : "add", (long) e->e_id, e->e_dn ); return LDAP_SUCCESS;