/* Get the list of which indices apply to this attr */ int mdb_index_recset( struct mdb_info *mdb, Attribute *a, AttributeType *type, struct berval *tags, IndexRec *ir ) { int rc, slot; AttrList *al; if( type->sat_sup ) { /* recurse */ rc = mdb_index_recset( mdb, 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 = mdb_attr_slot( mdb, type->sat_ad, NULL ); if ( slot >= 0 ) { ir[slot].ir_ai = mdb->mi_attrs[slot]; al = ch_malloc( sizeof( AttrList )); al->attr = a; al->next = ir[slot].ir_attrs; ir[slot].ir_attrs = al; } } if( tags->bv_len ) { AttributeDescription *desc; desc = ad_find_tags( type, tags ); if( desc ) { slot = mdb_attr_slot( mdb, desc, NULL ); if ( slot >= 0 ) { ir[slot].ir_ai = mdb->mi_attrs[slot]; al = ch_malloc( sizeof( AttrList )); al->attr = a; al->next = ir[slot].ir_attrs; ir[slot].ir_attrs = al; } } } return LDAP_SUCCESS; }
static int mdb_tool_index_add( Operation *op, MDB_txn *txn, Entry *e ) { struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private; if ( !mdb->mi_nattrs ) return 0; if ( mdb_tool_threads > 1 ) { IndexRec *ir; int i, rc; Attribute *a; ir = mdb_tool_index_rec; for (i=0; i<mdb->mi_nattrs; i++) ir[i].ir_attrs = NULL; for ( a = e->e_attrs; a != NULL; a = a->a_next ) { rc = mdb_index_recset( mdb, a, a->a_desc->ad_type, &a->a_desc->ad_tags, ir ); if ( rc ) return rc; } for (i=0; i<mdb->mi_nattrs; i++) { if ( !ir[i].ir_ai ) break; rc = mdb_cursor_open( txn, ir[i].ir_ai->ai_dbi, &ir[i].ir_ai->ai_cursor ); if ( rc ) return rc; } mdb_tool_ix_id = e->e_id; mdb_tool_ix_op = op; mdb_tool_ix_txn = txn; ldap_pvt_thread_mutex_lock( &mdb_tool_index_mutex ); /* Wait for all threads to be ready */ while ( mdb_tool_index_tcount ) { ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, &mdb_tool_index_mutex ); } for ( i=1; i<mdb_tool_threads; i++ ) mdb_tool_index_rec[i].ir_i = LDAP_BUSY; mdb_tool_index_tcount = mdb_tool_threads - 1; ldap_pvt_thread_mutex_unlock( &mdb_tool_index_mutex ); ldap_pvt_thread_cond_broadcast( &mdb_tool_index_cond_work ); rc = mdb_index_recrun( op, txn, mdb, ir, e->e_id, 0 ); if ( rc ) return rc; ldap_pvt_thread_mutex_lock( &mdb_tool_index_mutex ); for ( i=1; i<mdb_tool_threads; i++ ) { if ( mdb_tool_index_rec[i].ir_i == LDAP_BUSY ) { ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, &mdb_tool_index_mutex ); i--; continue; } if ( mdb_tool_index_rec[i].ir_i ) { rc = mdb_tool_index_rec[i].ir_i; break; } } ldap_pvt_thread_mutex_unlock( &mdb_tool_index_mutex ); return rc; } else { return mdb_index_entry_add( op, txn, e ); } }