mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
Dynamic indexing support
This commit is contained in:
parent
eac3fc3737
commit
5de908e7e1
@ -25,14 +25,6 @@
|
||||
#include "back-bdb.h"
|
||||
#include "lutil.h"
|
||||
|
||||
/* for the cache of attribute information (which are indexed, etc.) */
|
||||
typedef struct bdb_attrinfo {
|
||||
AttributeDescription *ai_desc; /* attribute description cn;lang-en */
|
||||
slap_mask_t ai_indexmask; /* how the attr is indexed */
|
||||
#ifdef LDAP_COMP_MATCH
|
||||
ComponentReference* ai_cr; /*component indexing*/
|
||||
#endif
|
||||
} AttrInfo;
|
||||
|
||||
static int
|
||||
ainfo_type_cmp(
|
||||
@ -55,50 +47,13 @@ ainfo_cmp(
|
||||
return SLAP_PTRCMP(a->ai_desc, b->ai_desc);
|
||||
}
|
||||
|
||||
#ifdef LDAP_COMP_MATCH
|
||||
void
|
||||
bdb_attr_comp_ref(
|
||||
struct bdb_info *bdb,
|
||||
AttributeDescription *desc,
|
||||
ComponentReference** cr )
|
||||
{
|
||||
AttrInfo *a;
|
||||
|
||||
a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
|
||||
|
||||
*cr = a != NULL ? a->ai_cr : 0 ;
|
||||
}
|
||||
void
|
||||
bdb_attr_mask_cr(
|
||||
struct bdb_info *bdb,
|
||||
AttributeDescription *desc,
|
||||
slap_mask_t *indexmask,
|
||||
ComponentReference** cr )
|
||||
{
|
||||
AttrInfo *a;
|
||||
|
||||
a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
|
||||
if ( a ) {
|
||||
*indexmask = a->ai_indexmask;
|
||||
*cr = a->ai_cr;
|
||||
} else {
|
||||
*indexmask = 0;
|
||||
*cr = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
AttrInfo *
|
||||
bdb_attr_mask(
|
||||
struct bdb_info *bdb,
|
||||
AttributeDescription *desc,
|
||||
slap_mask_t *indexmask )
|
||||
AttributeDescription *desc )
|
||||
{
|
||||
AttrInfo *a;
|
||||
|
||||
a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
|
||||
|
||||
*indexmask = a != NULL ? a->ai_indexmask : 0;
|
||||
return avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
|
||||
}
|
||||
|
||||
int
|
||||
@ -254,7 +209,15 @@ bdb_attr_index_config(
|
||||
ad->ad_cname.bv_val, mask, 0 );
|
||||
|
||||
a->ai_desc = ad;
|
||||
|
||||
if ( bdb->bi_flags & BDB_IS_OPEN ) {
|
||||
a->ai_indexmask = 0;
|
||||
a->ai_newmask = mask;
|
||||
} else {
|
||||
a->ai_indexmask = mask;
|
||||
a->ai_newmask = 0;
|
||||
}
|
||||
|
||||
#ifdef LDAP_COMP_MATCH
|
||||
if ( cr ) {
|
||||
a_cr = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp );
|
||||
@ -283,6 +246,17 @@ bdb_attr_index_config(
|
||||
ainfo_cmp, avl_dup_error );
|
||||
|
||||
if( rc ) {
|
||||
if ( bdb->bi_flags & BDB_IS_OPEN ) {
|
||||
AttrInfo *b = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp );
|
||||
/* If we were editing this attr, reset it */
|
||||
b->ai_indexmask &= ~BDB_INDEX_DELETING;
|
||||
/* If this is leftover from a previous add, commit it */
|
||||
if ( b->ai_newmask )
|
||||
b->ai_indexmask = b->ai_newmask;
|
||||
b->ai_newmask = a->ai_newmask;
|
||||
ch_free( a );
|
||||
continue;
|
||||
}
|
||||
fprintf( stderr, "%s: line %d: duplicate index definition "
|
||||
"for attr \"%s\" (ignored)\n",
|
||||
fname, lineno, attrs[i] );
|
||||
@ -353,3 +327,38 @@ void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad )
|
||||
if ( ai )
|
||||
bdb_attrinfo_free( ai );
|
||||
}
|
||||
|
||||
/* Get a list of AttrInfo's to delete */
|
||||
|
||||
typedef struct Alist {
|
||||
struct Alist *next;
|
||||
AttrInfo *ptr;
|
||||
} Alist;
|
||||
|
||||
static int
|
||||
bdb_attrinfo_flush( void *v1, void *arg )
|
||||
{
|
||||
AttrInfo *ai = v1;
|
||||
|
||||
if ( ai->ai_indexmask & BDB_INDEX_DELETING ) {
|
||||
Alist **al = arg;
|
||||
Alist *a = ch_malloc( sizeof( Alist ));
|
||||
a->ptr = ai;
|
||||
a->next = *al;
|
||||
*al = a;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bdb_attr_flush( struct bdb_info *bdb )
|
||||
{
|
||||
Alist *al = NULL, *a2;
|
||||
|
||||
avl_apply( bdb->bi_attrs, bdb_attrinfo_flush, &al, -1, AVL_INORDER );
|
||||
|
||||
while (( a2 = al )) {
|
||||
al = al->next;
|
||||
avl_delete( &bdb->bi_attrs, a2->ptr, ainfo_cmp );
|
||||
ch_free( a2 );
|
||||
}
|
||||
}
|
||||
|
@ -187,8 +187,11 @@ struct bdb_info {
|
||||
alock_info_t bi_alock_info;
|
||||
char *bi_db_config_path;
|
||||
BerVarray bi_db_config;
|
||||
int bi_db_is_open;
|
||||
int bi_db_has_config;
|
||||
int bi_flags;
|
||||
#define BDB_IS_OPEN 0x01
|
||||
#define BDB_HAS_CONFIG 0x02
|
||||
#define BDB_UPD_CONFIG 0x04
|
||||
#define BDB_DEL_INDEX 0x08
|
||||
};
|
||||
|
||||
#define bi_id2entry bi_databases[BDB_ID2ENTRY]
|
||||
@ -272,6 +275,20 @@ struct bdb_op_info {
|
||||
|
||||
LDAP_END_DECL
|
||||
|
||||
/* for the cache of attribute information (which are indexed, etc.) */
|
||||
typedef struct bdb_attrinfo {
|
||||
AttributeDescription *ai_desc; /* attribute description cn;lang-en */
|
||||
slap_mask_t ai_indexmask; /* how the attr is indexed */
|
||||
slap_mask_t ai_newmask; /* new settings to replace old mask */
|
||||
#ifdef LDAP_COMP_MATCH
|
||||
ComponentReference* ai_cr; /*component indexing*/
|
||||
#endif
|
||||
} AttrInfo;
|
||||
|
||||
/* These flags must not clash with SLAP_INDEX flags or ops in slap.h! */
|
||||
#define BDB_INDEX_DELETING 0x8000U /* index is being modified */
|
||||
#define BDB_INDEX_UPDATE_OP 0x03 /* performing an index update */
|
||||
|
||||
#include "proto-bdb.h"
|
||||
|
||||
#endif /* _BACK_BDB_H_ */
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "lutil.h"
|
||||
#include "ldap_rq.h"
|
||||
|
||||
#ifdef DB_DIRTY_READ
|
||||
# define SLAP_BDB_ALLOW_DIRTY_READ
|
||||
@ -86,6 +87,7 @@ static ConfigTable bdbcfg[] = {
|
||||
{ "index", "attr> <[pres,eq,approx,sub]", 2, 3, 0, ARG_MAGIC|BDB_INDEX,
|
||||
bdb_cf_gen, "( OLcfgDbAt:0.2 NAME 'olcDbIndex' "
|
||||
"DESC 'Attribute index parameters' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString )", NULL, NULL },
|
||||
{ "linearindex", NULL, 1, 2, 0, ARG_ON_OFF|ARG_OFFSET,
|
||||
(void *)offsetof(struct bdb_info, bi_linear_index),
|
||||
@ -147,6 +149,141 @@ static slap_verbmasks bdb_lockd[] = {
|
||||
{ BER_BVNULL, 0 }
|
||||
};
|
||||
|
||||
/* reindex entries on the fly */
|
||||
static void *
|
||||
bdb_online_index( void *ctx, void *arg )
|
||||
{
|
||||
struct re_s *rtask = arg;
|
||||
BackendDB *be = rtask->arg;
|
||||
struct bdb_info *bdb = be->be_private;
|
||||
|
||||
Connection conn = {0};
|
||||
char opbuf[OPERATION_BUFFER_SIZE];
|
||||
Operation *op = (Operation *)opbuf;
|
||||
|
||||
DBC *curs;
|
||||
DBT key, data;
|
||||
DB_TXN *txn;
|
||||
DB_LOCK lock;
|
||||
u_int32_t locker;
|
||||
ID id, nid;
|
||||
EntryInfo *ei;
|
||||
int rc, getnext = 1;
|
||||
|
||||
connection_fake_init( &conn, op, ctx );
|
||||
|
||||
op->o_bd = be;
|
||||
|
||||
DBTzero( &key );
|
||||
DBTzero( &data );
|
||||
|
||||
id = 1;
|
||||
key.data = &nid;
|
||||
key.size = key.ulen = sizeof(ID);
|
||||
key.flags = DB_DBT_USERMEM;
|
||||
|
||||
data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
|
||||
data.dlen = data.ulen = 0;
|
||||
|
||||
while ( 1 ) {
|
||||
rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &txn, bdb->bi_db_opflags );
|
||||
if ( rc )
|
||||
break;
|
||||
locker = TXN_ID( txn );
|
||||
if ( getnext ) {
|
||||
getnext = 0;
|
||||
BDB_ID2DISK( id, &nid );
|
||||
rc = bdb->bi_id2entry->bdi_db->cursor(
|
||||
bdb->bi_id2entry->bdi_db, txn, &curs, bdb->bi_db_opflags );
|
||||
if ( rc ) {
|
||||
TXN_ABORT( txn );
|
||||
break;
|
||||
}
|
||||
rc = curs->c_get( curs, &key, &data, DB_SET_RANGE );
|
||||
curs->c_close( curs );
|
||||
if ( rc ) {
|
||||
TXN_ABORT( txn );
|
||||
if ( rc == DB_NOTFOUND )
|
||||
rc = 0;
|
||||
if ( rc == DB_LOCK_DEADLOCK ) {
|
||||
ldap_pvt_thread_yield();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
BDB_DISK2ID( &nid, &id );
|
||||
}
|
||||
|
||||
ei = NULL;
|
||||
rc = bdb_cache_find_id( op, txn, id, &ei, 0, locker, &lock );
|
||||
if ( rc ) {
|
||||
TXN_ABORT( txn );
|
||||
if ( rc == DB_LOCK_DEADLOCK ) {
|
||||
ldap_pvt_thread_yield();
|
||||
continue;
|
||||
}
|
||||
if ( rc == DB_NOTFOUND ) {
|
||||
id++
|
||||
getnext = 1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( ei->bei_e ) {
|
||||
rc = bdb_index_entry( op, txn, BDB_INDEX_UPDATE_OP, ei->bei_e );
|
||||
if ( rc == DB_LOCK_DEADLOCK ) {
|
||||
TXN_ABORT( txn );
|
||||
ldap_pvt_thread_yield();
|
||||
continue;
|
||||
}
|
||||
if ( rc == 0 ) {
|
||||
rc = TXN_COMMIT( txn, 0 );
|
||||
txn = NULL;
|
||||
}
|
||||
if ( rc )
|
||||
break;
|
||||
}
|
||||
id++;
|
||||
getnext = 1;
|
||||
}
|
||||
out:
|
||||
ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
|
||||
ldap_pvt_runqueue_stoptask( &slapd_rq, rtask );
|
||||
ldap_pvt_runqueue_remove( &slapd_rq, rtask );
|
||||
ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Cleanup loose ends after Modify completes */
|
||||
static int
|
||||
bdb_cf_cleanup( ConfigArgs *c )
|
||||
{
|
||||
struct bdb_info *bdb = c->be->be_private;
|
||||
|
||||
if ( bdb->bi_flags & BDB_UPD_CONFIG ) {
|
||||
if ( bdb->bi_db_config ) {
|
||||
int i;
|
||||
FILE *f = fopen( bdb->bi_db_config_path, "w" );
|
||||
if ( f ) {
|
||||
for (i=0; bdb->bi_db_config[i].bv_val; i++)
|
||||
fprintf( f, "%s\n", bdb->bi_db_config[i].bv_val );
|
||||
fclose( f );
|
||||
}
|
||||
} else {
|
||||
unlink( bdb->bi_db_config_path );
|
||||
}
|
||||
bdb->bi_flags ^= BDB_UPD_CONFIG;
|
||||
}
|
||||
|
||||
if ( bdb->bi_flags & BDB_DEL_INDEX ) {
|
||||
bdb_attr_flush( bdb );
|
||||
bdb->bi_flags ^= BDB_DEL_INDEX;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bdb_cf_gen(ConfigArgs *c)
|
||||
{
|
||||
@ -234,8 +371,17 @@ bdb_cf_gen(ConfigArgs *c)
|
||||
bdb->bi_txn_cp = 0;
|
||||
break;
|
||||
case BDB_CONFIG:
|
||||
rc = 1;
|
||||
/* FIXME: delete values or the whole file? */
|
||||
if ( c->valx < 0 ) {
|
||||
ber_bvarray_free( bdb->bi_db_config );
|
||||
bdb->bi_db_config = NULL;
|
||||
} else {
|
||||
int i = c->valx;
|
||||
ch_free( bdb->bi_db_config[i].bv_val );
|
||||
for (; bdb->bi_db_config[i].bv_val; i++)
|
||||
bdb->bi_db_config[i] = bdb->bi_db_config[i+1];
|
||||
}
|
||||
bdb->bi_flags |= BDB_UPD_CONFIG;
|
||||
c->cleanup = bdb_cf_cleanup;
|
||||
break;
|
||||
case BDB_DIRECTORY:
|
||||
rc = 1;
|
||||
@ -252,12 +398,16 @@ bdb_cf_gen(ConfigArgs *c)
|
||||
for (ptr = c->line; !isspace( *ptr ); ptr++);
|
||||
bv.bv_val = c->line;
|
||||
bv.bv_len = ptr - bv.bv_val;
|
||||
if ( ber_bvmatch( &bv, &defbv )) {
|
||||
if ( bvmatch( &bv, &def )) {
|
||||
bdb->bi_defaultmask = 0;
|
||||
} else {
|
||||
slap_bv2ad( &bv, &ad, &text );
|
||||
if ( ad )
|
||||
bdb_attr_index_free( bdb, ad );
|
||||
if ( ad ) {
|
||||
AttrInfo *ai = bdb_attr_mask( bdb, ad );
|
||||
ai->ai_indexmask |= BDB_INDEX_DELETING;
|
||||
bdb->bi_flags |= BDB_DEL_INDEX;
|
||||
c->cleanup = bdb_cf_cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -278,14 +428,17 @@ bdb_cf_gen(ConfigArgs *c)
|
||||
while (!isspace(*ptr)) ptr++;
|
||||
while (isspace(*ptr)) ptr++;
|
||||
|
||||
if ( bdb->bi_flags & BDB_IS_OPEN ) {
|
||||
bdb->bi_flags |= BDB_UPD_CONFIG;
|
||||
c->cleanup = bdb_cf_cleanup;
|
||||
} else {
|
||||
/* If we're just starting up...
|
||||
*/
|
||||
if ( !bdb->bi_db_is_open ) {
|
||||
FILE *f;
|
||||
/* If a DB_CONFIG file exists, or we don't know the path
|
||||
* to the DB_CONFIG file, ignore these directives
|
||||
*/
|
||||
if ( bdb->bi_db_has_config || !bdb->bi_db_config_path )
|
||||
if (( bdb->bi_flags & BDB_HAS_CONFIG ) || !bdb->bi_db_config_path )
|
||||
break;
|
||||
f = fopen( bdb->bi_db_config_path, "a" );
|
||||
if ( f ) {
|
||||
@ -314,7 +467,7 @@ bdb_cf_gen(ConfigArgs *c)
|
||||
|
||||
f = fopen( bdb->bi_db_config_path, "r" );
|
||||
if ( f ) {
|
||||
bdb->bi_db_has_config = 1;
|
||||
bdb->bi_flags |= BDB_HAS_CONFIG;
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
@ -325,7 +478,7 @@ bdb_cf_gen(ConfigArgs *c)
|
||||
bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC;
|
||||
else
|
||||
bdb->bi_dbenv_xflags &= ~DB_TXN_NOSYNC;
|
||||
if ( bdb->bi_db_is_open ) {
|
||||
if ( bdb->bi_flags & BDB_IS_OPEN ) {
|
||||
bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC,
|
||||
c->value_int );
|
||||
}
|
||||
@ -336,8 +489,10 @@ bdb_cf_gen(ConfigArgs *c)
|
||||
c->argc - 1, &c->argv[1] );
|
||||
|
||||
if( rc != LDAP_SUCCESS ) return 1;
|
||||
/* FIXME: must run slapindex on the new attributes */
|
||||
if ( bdb->bi_db_is_open ) {
|
||||
if ( bdb->bi_flags & BDB_IS_OPEN ) {
|
||||
/* Start the task as soon as we finish here */
|
||||
ldap_pvt_runqueue_insert( &slapd_rq, 60,
|
||||
bdb_online_index, c->be );
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -297,12 +297,16 @@ comp_equality_candidates (
|
||||
MatchingRule *mr = mra->ma_rule;
|
||||
Syntax *sat_syntax;
|
||||
ComponentReference* cr_list, *cr;
|
||||
AttrInfo *ai;
|
||||
|
||||
BDB_IDL_ALL( bdb, ids );
|
||||
|
||||
bdb_attr_comp_ref ( op->o_bd->be_private, mra->ma_desc, &cr_list );
|
||||
if( !cr_list || !ca->ca_comp_ref )
|
||||
if ( !ca->ca_comp_ref )
|
||||
return 0;
|
||||
|
||||
ai = bdb_attr_mask( op->o_bd->be_private, mra->ma_desc );
|
||||
if( ai )
|
||||
cr_list = ai->ai_cr;
|
||||
/* find a component reference to be indexed */
|
||||
sat_syntax = ca->ca_ma_rule->smr_syntax;
|
||||
for ( cr = cr_list ; cr ; cr = cr->cr_next ) {
|
||||
|
@ -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;
|
||||
AttrInfo *ai = bdb_attr_mask( be->be_private, desc );
|
||||
|
||||
bdb_attr_mask( be->be_private, desc, &mask );
|
||||
|
||||
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 );
|
||||
|
||||
@ -268,6 +269,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,52 +286,62 @@ 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 ) {
|
||||
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, opid,
|
||||
cr->cr_indexmask );
|
||||
}
|
||||
}
|
||||
#else
|
||||
bdb_attr_mask( op->o_bd->be_private, type->sat_ad, &mask );
|
||||
#endif
|
||||
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, opid,
|
||||
mask );
|
||||
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 );
|
||||
}
|
||||
ai = bdb_attr_mask( op->o_bd->be_private, desc );
|
||||
|
||||
if( mask ) {
|
||||
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, opid,
|
||||
mask );
|
||||
vals, id, ixop, mask );
|
||||
|
||||
if( rc ) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
@ -373,14 +389,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 );
|
||||
@ -443,7 +462,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;
|
||||
|
@ -546,7 +546,7 @@ bdb_db_open( BackendDB *be )
|
||||
ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
|
||||
}
|
||||
|
||||
if ( slapMode & SLAP_SERVER_MODE && bdb->bi_db_has_config ) {
|
||||
if (( slapMode&SLAP_SERVER_MODE ) && ( bdb->bi_flags&BDB_HAS_CONFIG )) {
|
||||
char buf[SLAP_TEXT_BUFLEN];
|
||||
FILE *f = fopen( bdb->bi_db_config_path, "r" );
|
||||
struct berval bv;
|
||||
@ -568,11 +568,11 @@ bdb_db_open( BackendDB *be )
|
||||
fclose( f );
|
||||
} else {
|
||||
/* Eh? It disappeared between config and open?? */
|
||||
bdb->bi_db_has_config = 0;
|
||||
bdb->bi_flags &= ~BDB_HAS_CONFIG;
|
||||
}
|
||||
|
||||
}
|
||||
bdb->bi_db_is_open = 1;
|
||||
bdb->bi_flags |= BDB_IS_OPEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -585,7 +585,7 @@ bdb_db_close( BackendDB *be )
|
||||
struct bdb_db_info *db;
|
||||
bdb_idl_cache_entry_t *entry, *next_entry;
|
||||
|
||||
bdb->bi_db_is_open = 0;
|
||||
bdb->bi_flags &= ~BDB_IS_OPEN;
|
||||
|
||||
ber_bvarray_free( bdb->bi_db_config );
|
||||
|
||||
|
@ -31,26 +31,16 @@ LDAP_BEGIN_DECL
|
||||
*/
|
||||
|
||||
#define bdb_attr_mask BDB_SYMBOL(attr_mask)
|
||||
#define bdb_attr_flush BDB_SYMBOL(attr_flush)
|
||||
#define bdb_attr_index_config BDB_SYMBOL(attr_index_config)
|
||||
#define bdb_attr_index_destroy BDB_SYMBOL(attr_index_destroy)
|
||||
#define bdb_attr_index_free BDB_SYMBOL(attr_index_free)
|
||||
#define bdb_attr_index_unparse BDB_SYMBOL(attr_index_unparse)
|
||||
|
||||
#ifdef LDAP_COMP_MATCH
|
||||
#define bdb_attr_comp_ref BDB_SYMBOL(attr_comp_ref)
|
||||
#define bdb_attr_mask_cr BDB_SYMBOL(attr_mask_cr)
|
||||
void bdb_attr_comp_ref( struct bdb_info *bdb,
|
||||
AttributeDescription *desc,
|
||||
ComponentReference **cr );
|
||||
void bdb_attr_mask_cr( struct bdb_info *bdb,
|
||||
AttributeDescription *desc,
|
||||
slap_mask_t *indexmask,
|
||||
ComponentReference **cr );
|
||||
#endif
|
||||
AttrInfo *bdb_attr_mask( struct bdb_info *bdb,
|
||||
AttributeDescription *desc );
|
||||
|
||||
void bdb_attr_mask( struct bdb_info *bdb,
|
||||
AttributeDescription *desc,
|
||||
slap_mask_t *indexmask );
|
||||
void bdb_attr_flush( struct bdb_info *bdb );
|
||||
|
||||
int bdb_attr_index_config LDAP_P(( struct bdb_info *bdb,
|
||||
const char *fname, int lineno,
|
||||
|
Loading…
Reference in New Issue
Block a user