mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-24 13:24:56 +08:00
Dynamic indexing support
This commit is contained in:
parent
eac3fc3737
commit
5de908e7e1
@ -25,14 +25,6 @@
|
|||||||
#include "back-bdb.h"
|
#include "back-bdb.h"
|
||||||
#include "lutil.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
|
static int
|
||||||
ainfo_type_cmp(
|
ainfo_type_cmp(
|
||||||
@ -55,50 +47,13 @@ ainfo_cmp(
|
|||||||
return SLAP_PTRCMP(a->ai_desc, b->ai_desc);
|
return SLAP_PTRCMP(a->ai_desc, b->ai_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LDAP_COMP_MATCH
|
AttrInfo *
|
||||||
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
|
|
||||||
bdb_attr_mask(
|
bdb_attr_mask(
|
||||||
struct bdb_info *bdb,
|
struct bdb_info *bdb,
|
||||||
AttributeDescription *desc,
|
AttributeDescription *desc )
|
||||||
slap_mask_t *indexmask )
|
|
||||||
{
|
{
|
||||||
AttrInfo *a;
|
|
||||||
|
|
||||||
a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
|
return avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
|
||||||
|
|
||||||
*indexmask = a != NULL ? a->ai_indexmask : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -254,7 +209,15 @@ bdb_attr_index_config(
|
|||||||
ad->ad_cname.bv_val, mask, 0 );
|
ad->ad_cname.bv_val, mask, 0 );
|
||||||
|
|
||||||
a->ai_desc = ad;
|
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_indexmask = mask;
|
||||||
|
a->ai_newmask = 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef LDAP_COMP_MATCH
|
#ifdef LDAP_COMP_MATCH
|
||||||
if ( cr ) {
|
if ( cr ) {
|
||||||
a_cr = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp );
|
a_cr = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp );
|
||||||
@ -283,6 +246,17 @@ bdb_attr_index_config(
|
|||||||
ainfo_cmp, avl_dup_error );
|
ainfo_cmp, avl_dup_error );
|
||||||
|
|
||||||
if( rc ) {
|
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 "
|
fprintf( stderr, "%s: line %d: duplicate index definition "
|
||||||
"for attr \"%s\" (ignored)\n",
|
"for attr \"%s\" (ignored)\n",
|
||||||
fname, lineno, attrs[i] );
|
fname, lineno, attrs[i] );
|
||||||
@ -353,3 +327,38 @@ void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad )
|
|||||||
if ( ai )
|
if ( ai )
|
||||||
bdb_attrinfo_free( 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;
|
alock_info_t bi_alock_info;
|
||||||
char *bi_db_config_path;
|
char *bi_db_config_path;
|
||||||
BerVarray bi_db_config;
|
BerVarray bi_db_config;
|
||||||
int bi_db_is_open;
|
int bi_flags;
|
||||||
int bi_db_has_config;
|
#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]
|
#define bi_id2entry bi_databases[BDB_ID2ENTRY]
|
||||||
@ -272,6 +275,20 @@ struct bdb_op_info {
|
|||||||
|
|
||||||
LDAP_END_DECL
|
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"
|
#include "proto-bdb.h"
|
||||||
|
|
||||||
#endif /* _BACK_BDB_H_ */
|
#endif /* _BACK_BDB_H_ */
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "lutil.h"
|
#include "lutil.h"
|
||||||
|
#include "ldap_rq.h"
|
||||||
|
|
||||||
#ifdef DB_DIRTY_READ
|
#ifdef DB_DIRTY_READ
|
||||||
# define SLAP_BDB_ALLOW_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,
|
{ "index", "attr> <[pres,eq,approx,sub]", 2, 3, 0, ARG_MAGIC|BDB_INDEX,
|
||||||
bdb_cf_gen, "( OLcfgDbAt:0.2 NAME 'olcDbIndex' "
|
bdb_cf_gen, "( OLcfgDbAt:0.2 NAME 'olcDbIndex' "
|
||||||
"DESC 'Attribute index parameters' "
|
"DESC 'Attribute index parameters' "
|
||||||
|
"EQUALITY caseIgnoreMatch "
|
||||||
"SYNTAX OMsDirectoryString )", NULL, NULL },
|
"SYNTAX OMsDirectoryString )", NULL, NULL },
|
||||||
{ "linearindex", NULL, 1, 2, 0, ARG_ON_OFF|ARG_OFFSET,
|
{ "linearindex", NULL, 1, 2, 0, ARG_ON_OFF|ARG_OFFSET,
|
||||||
(void *)offsetof(struct bdb_info, bi_linear_index),
|
(void *)offsetof(struct bdb_info, bi_linear_index),
|
||||||
@ -147,6 +149,141 @@ static slap_verbmasks bdb_lockd[] = {
|
|||||||
{ BER_BVNULL, 0 }
|
{ 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
|
static int
|
||||||
bdb_cf_gen(ConfigArgs *c)
|
bdb_cf_gen(ConfigArgs *c)
|
||||||
{
|
{
|
||||||
@ -234,8 +371,17 @@ bdb_cf_gen(ConfigArgs *c)
|
|||||||
bdb->bi_txn_cp = 0;
|
bdb->bi_txn_cp = 0;
|
||||||
break;
|
break;
|
||||||
case BDB_CONFIG:
|
case BDB_CONFIG:
|
||||||
rc = 1;
|
if ( c->valx < 0 ) {
|
||||||
/* FIXME: delete values or the whole file? */
|
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;
|
break;
|
||||||
case BDB_DIRECTORY:
|
case BDB_DIRECTORY:
|
||||||
rc = 1;
|
rc = 1;
|
||||||
@ -252,12 +398,16 @@ bdb_cf_gen(ConfigArgs *c)
|
|||||||
for (ptr = c->line; !isspace( *ptr ); ptr++);
|
for (ptr = c->line; !isspace( *ptr ); ptr++);
|
||||||
bv.bv_val = c->line;
|
bv.bv_val = c->line;
|
||||||
bv.bv_len = ptr - bv.bv_val;
|
bv.bv_len = ptr - bv.bv_val;
|
||||||
if ( ber_bvmatch( &bv, &defbv )) {
|
if ( bvmatch( &bv, &def )) {
|
||||||
bdb->bi_defaultmask = 0;
|
bdb->bi_defaultmask = 0;
|
||||||
} else {
|
} else {
|
||||||
slap_bv2ad( &bv, &ad, &text );
|
slap_bv2ad( &bv, &ad, &text );
|
||||||
if ( ad )
|
if ( ad ) {
|
||||||
bdb_attr_index_free( bdb, 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;
|
break;
|
||||||
@ -278,14 +428,17 @@ bdb_cf_gen(ConfigArgs *c)
|
|||||||
while (!isspace(*ptr)) ptr++;
|
while (!isspace(*ptr)) ptr++;
|
||||||
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 we're just starting up...
|
||||||
*/
|
*/
|
||||||
if ( !bdb->bi_db_is_open ) {
|
|
||||||
FILE *f;
|
FILE *f;
|
||||||
/* If a DB_CONFIG file exists, or we don't know the path
|
/* If a DB_CONFIG file exists, or we don't know the path
|
||||||
* to the DB_CONFIG file, ignore these directives
|
* 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;
|
break;
|
||||||
f = fopen( bdb->bi_db_config_path, "a" );
|
f = fopen( bdb->bi_db_config_path, "a" );
|
||||||
if ( f ) {
|
if ( f ) {
|
||||||
@ -314,7 +467,7 @@ bdb_cf_gen(ConfigArgs *c)
|
|||||||
|
|
||||||
f = fopen( bdb->bi_db_config_path, "r" );
|
f = fopen( bdb->bi_db_config_path, "r" );
|
||||||
if ( f ) {
|
if ( f ) {
|
||||||
bdb->bi_db_has_config = 1;
|
bdb->bi_flags |= BDB_HAS_CONFIG;
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,7 +478,7 @@ bdb_cf_gen(ConfigArgs *c)
|
|||||||
bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC;
|
bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC;
|
||||||
else
|
else
|
||||||
bdb->bi_dbenv_xflags &= ~DB_TXN_NOSYNC;
|
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,
|
bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC,
|
||||||
c->value_int );
|
c->value_int );
|
||||||
}
|
}
|
||||||
@ -336,8 +489,10 @@ bdb_cf_gen(ConfigArgs *c)
|
|||||||
c->argc - 1, &c->argv[1] );
|
c->argc - 1, &c->argv[1] );
|
||||||
|
|
||||||
if( rc != LDAP_SUCCESS ) return 1;
|
if( rc != LDAP_SUCCESS ) return 1;
|
||||||
/* FIXME: must run slapindex on the new attributes */
|
if ( bdb->bi_flags & BDB_IS_OPEN ) {
|
||||||
if ( bdb->bi_db_is_open ) {
|
/* Start the task as soon as we finish here */
|
||||||
|
ldap_pvt_runqueue_insert( &slapd_rq, 60,
|
||||||
|
bdb_online_index, c->be );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -297,12 +297,16 @@ comp_equality_candidates (
|
|||||||
MatchingRule *mr = mra->ma_rule;
|
MatchingRule *mr = mra->ma_rule;
|
||||||
Syntax *sat_syntax;
|
Syntax *sat_syntax;
|
||||||
ComponentReference* cr_list, *cr;
|
ComponentReference* cr_list, *cr;
|
||||||
|
AttrInfo *ai;
|
||||||
|
|
||||||
BDB_IDL_ALL( bdb, ids );
|
BDB_IDL_ALL( bdb, ids );
|
||||||
|
|
||||||
bdb_attr_comp_ref ( op->o_bd->be_private, mra->ma_desc, &cr_list );
|
if ( !ca->ca_comp_ref )
|
||||||
if( !cr_list || !ca->ca_comp_ref )
|
|
||||||
return 0;
|
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 */
|
/* find a component reference to be indexed */
|
||||||
sat_syntax = ca->ca_ma_rule->smr_syntax;
|
sat_syntax = ca->ca_ma_rule->smr_syntax;
|
||||||
for ( cr = cr_list ; cr ; cr = cr->cr_next ) {
|
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 char presence_keyval[LUTIL_HASH_BYTES] = {0,0,0,1};
|
||||||
static struct berval presence_key = {LUTIL_HASH_BYTES, presence_keyval};
|
static struct berval presence_key = {LUTIL_HASH_BYTES, presence_keyval};
|
||||||
|
|
||||||
static slap_mask_t index_mask(
|
static AttrInfo *index_mask(
|
||||||
Backend *be,
|
Backend *be,
|
||||||
AttributeDescription *desc,
|
AttributeDescription *desc,
|
||||||
struct berval *atname )
|
struct berval *atname )
|
||||||
{
|
{
|
||||||
AttributeType *at;
|
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( ai ) {
|
||||||
|
|
||||||
if( mask ) {
|
|
||||||
*atname = desc->ad_cname;
|
*atname = desc->ad_cname;
|
||||||
return mask;
|
return ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there is a tagging option, did we ever index the base
|
/* 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 ) {
|
if( slap_ad_is_tagged( desc ) && desc != desc->ad_type->sat_ad ) {
|
||||||
/* has tagging option */
|
/* 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;
|
*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 no AD, we've never indexed this type */
|
||||||
if ( !at->sat_ad ) continue;
|
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;
|
*atname = at->sat_cname;
|
||||||
return mask;
|
return ai;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,18 +74,19 @@ int bdb_index_is_indexed(
|
|||||||
Backend *be,
|
Backend *be,
|
||||||
AttributeDescription *desc )
|
AttributeDescription *desc )
|
||||||
{
|
{
|
||||||
slap_mask_t mask;
|
AttrInfo *ai;
|
||||||
struct berval prefix;
|
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_INAPPROPRIATE_MATCHING;
|
||||||
}
|
|
||||||
|
|
||||||
return LDAP_SUCCESS;
|
return LDAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function is only called when evaluating search filters.
|
||||||
|
*/
|
||||||
int bdb_index_param(
|
int bdb_index_param(
|
||||||
Backend *be,
|
Backend *be,
|
||||||
AttributeDescription *desc,
|
AttributeDescription *desc,
|
||||||
@ -96,15 +95,17 @@ int bdb_index_param(
|
|||||||
slap_mask_t *maskp,
|
slap_mask_t *maskp,
|
||||||
struct berval *prefixp )
|
struct berval *prefixp )
|
||||||
{
|
{
|
||||||
|
AttrInfo *ai;
|
||||||
int rc;
|
int rc;
|
||||||
slap_mask_t mask;
|
slap_mask_t mask;
|
||||||
DB *db;
|
DB *db;
|
||||||
|
|
||||||
mask = index_mask( be, desc, prefixp );
|
ai = index_mask( be, desc, prefixp );
|
||||||
|
|
||||||
if( mask == 0 ) {
|
if( !ai ) {
|
||||||
return LDAP_INAPPROPRIATE_MATCHING;
|
return LDAP_INAPPROPRIATE_MATCHING;
|
||||||
}
|
}
|
||||||
|
mask = ai->ai_indexmask;
|
||||||
|
|
||||||
rc = bdb_db_cache( be, prefixp->bv_val, &db );
|
rc = bdb_db_cache( be, prefixp->bv_val, &db );
|
||||||
|
|
||||||
@ -268,6 +269,11 @@ static int index_at_values(
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
slap_mask_t mask = 0;
|
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 ) {
|
if( type->sat_sup ) {
|
||||||
/* recurse */
|
/* recurse */
|
||||||
@ -280,52 +286,62 @@ static int index_at_values(
|
|||||||
|
|
||||||
/* If this type has no AD, we've never used it before */
|
/* If this type has no AD, we've never used it before */
|
||||||
if( type->sat_ad ) {
|
if( type->sat_ad ) {
|
||||||
|
ai = bdb_attr_mask( op->o_bd->be_private, type->sat_ad );
|
||||||
|
if ( ai ) {
|
||||||
#ifdef LDAP_COMP_MATCH
|
#ifdef LDAP_COMP_MATCH
|
||||||
/* component indexing */
|
/* component indexing */
|
||||||
ComponentReference* cr_list, *cr;
|
if ( ai->ai_cr ) {
|
||||||
|
ComponentReference *cr;
|
||||||
bdb_attr_mask_cr( op->o_bd->be_private, type->sat_ad, &mask, &cr_list );
|
for( cr = ai->ai_cr ; cr ; cr = cr->cr_next ) {
|
||||||
if ( cr_list ) {
|
|
||||||
for( cr = cr_list ; cr ; cr = cr->cr_next ) {
|
|
||||||
rc = indexer( op, txn, cr->cr_ad, &type->sat_cname,
|
rc = indexer( op, txn, cr->cr_ad, &type->sat_cname,
|
||||||
cr->cr_nvals, id, opid,
|
cr->cr_nvals, id, opid,
|
||||||
cr->cr_indexmask );
|
cr->cr_indexmask );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
bdb_attr_mask( op->o_bd->be_private, type->sat_ad, &mask );
|
|
||||||
#endif
|
#endif
|
||||||
ad = type->sat_ad;
|
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 ) {
|
if( mask ) {
|
||||||
rc = indexer( op, txn, ad, &type->sat_cname,
|
rc = indexer( op, txn, ad, &type->sat_cname,
|
||||||
vals, id, opid,
|
vals, id, ixop, mask );
|
||||||
mask );
|
|
||||||
|
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( tags->bv_len ) {
|
if( tags->bv_len ) {
|
||||||
AttributeDescription *desc;
|
AttributeDescription *desc;
|
||||||
|
|
||||||
mask = 0;
|
|
||||||
|
|
||||||
desc = ad_find_tags( type, tags );
|
desc = ad_find_tags( type, tags );
|
||||||
if( desc ) {
|
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,
|
rc = indexer( op, txn, desc, &desc->ad_cname,
|
||||||
vals, id, opid,
|
vals, id, ixop, mask );
|
||||||
mask );
|
|
||||||
|
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return LDAP_SUCCESS;
|
return LDAP_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -373,14 +389,17 @@ bdb_index_entry(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n",
|
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 );
|
(long) e->e_id, e->e_dn );
|
||||||
|
|
||||||
/* add each attribute to the indexes */
|
/* add each attribute to the indexes */
|
||||||
for ( ; ap != NULL; ap = ap->a_next ) {
|
for ( ; ap != NULL; ap = ap->a_next ) {
|
||||||
#ifdef LDAP_COMP_MATCH
|
#ifdef LDAP_COMP_MATCH
|
||||||
|
AttrInfo *ai;
|
||||||
/* see if attribute has components to be indexed */
|
/* 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 ) {
|
if ( attr_converter && cr_list ) {
|
||||||
syn = ap->a_desc->ad_type->sat_syntax;
|
syn = ap->a_desc->ad_type->sat_syntax;
|
||||||
ap->a_comp_data = op->o_tmpalloc( sizeof( ComponentData ), op->o_tmpmemctx );
|
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",
|
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 );
|
(long) e->e_id, e->e_dn );
|
||||||
|
|
||||||
return LDAP_SUCCESS;
|
return LDAP_SUCCESS;
|
||||||
|
@ -546,7 +546,7 @@ bdb_db_open( BackendDB *be )
|
|||||||
ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
|
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];
|
char buf[SLAP_TEXT_BUFLEN];
|
||||||
FILE *f = fopen( bdb->bi_db_config_path, "r" );
|
FILE *f = fopen( bdb->bi_db_config_path, "r" );
|
||||||
struct berval bv;
|
struct berval bv;
|
||||||
@ -568,11 +568,11 @@ bdb_db_open( BackendDB *be )
|
|||||||
fclose( f );
|
fclose( f );
|
||||||
} else {
|
} else {
|
||||||
/* Eh? It disappeared between config and open?? */
|
/* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -585,7 +585,7 @@ bdb_db_close( BackendDB *be )
|
|||||||
struct bdb_db_info *db;
|
struct bdb_db_info *db;
|
||||||
bdb_idl_cache_entry_t *entry, *next_entry;
|
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 );
|
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_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_config BDB_SYMBOL(attr_index_config)
|
||||||
#define bdb_attr_index_destroy BDB_SYMBOL(attr_index_destroy)
|
#define bdb_attr_index_destroy BDB_SYMBOL(attr_index_destroy)
|
||||||
#define bdb_attr_index_free BDB_SYMBOL(attr_index_free)
|
#define bdb_attr_index_free BDB_SYMBOL(attr_index_free)
|
||||||
#define bdb_attr_index_unparse BDB_SYMBOL(attr_index_unparse)
|
#define bdb_attr_index_unparse BDB_SYMBOL(attr_index_unparse)
|
||||||
|
|
||||||
#ifdef LDAP_COMP_MATCH
|
AttrInfo *bdb_attr_mask( struct bdb_info *bdb,
|
||||||
#define bdb_attr_comp_ref BDB_SYMBOL(attr_comp_ref)
|
AttributeDescription *desc );
|
||||||
#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
|
|
||||||
|
|
||||||
void bdb_attr_mask( struct bdb_info *bdb,
|
void bdb_attr_flush( struct bdb_info *bdb );
|
||||||
AttributeDescription *desc,
|
|
||||||
slap_mask_t *indexmask );
|
|
||||||
|
|
||||||
int bdb_attr_index_config LDAP_P(( struct bdb_info *bdb,
|
int bdb_attr_index_config LDAP_P(( struct bdb_info *bdb,
|
||||||
const char *fname, int lineno,
|
const char *fname, int lineno,
|
||||||
|
Loading…
Reference in New Issue
Block a user