1 /* index.c - routines for dealing with attribute indexes */
11 #include "back-ldbm.h"
13 static int add_value(Backend *be,
19 static int delete_value(Backend *be,
25 static int index2prefix(int indextype);
35 struct berval *bvals[2];
37 Debug( LDAP_DEBUG_TRACE, "=> index_add( %ld, \"%s\" )\n", e->e_id,
41 * dn index entry - make it look like an attribute so it works
42 * with index_add_values() call
45 bv.bv_val = ch_strdup( e->e_ndn );
46 bv.bv_len = strlen( bv.bv_val );
50 /* add the dn to the indexes */
52 char *dn = ch_strdup("dn");
53 index_add_values( be, dn, bvals, e->e_id );
59 /* add each attribute to the indexes */
60 for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
62 index_add_values( be, ap->a_type, ap->a_vals, e->e_id );
65 Debug( LDAP_DEBUG_TRACE, "<= index_add( %ld, \"%s\" ) 0\n", e->e_id,
79 for ( ; ml != NULL; ml = ml->ml_next ) {
80 LDAPMod *mod = &ml->ml_mod;
82 switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) {
83 case LDAP_MOD_REPLACE:
84 /* XXX: Delete old index data==>problem when this
85 * gets called we lost values already!
88 rc = index_add_values( be, mod->mod_type,
89 mod->mod_bvalues, id );
92 rc = index_delete_values( be, mod->mod_type,
93 mod->mod_bvalues, id );
95 case LDAP_MOD_SOFTADD: /* SOFTADD means index was there */
119 int indexmask, syntax;
121 char *realval, *tmpval;
126 ldbm_datum_init( key );
128 prefix = index2prefix( indextype );
129 Debug( LDAP_DEBUG_TRACE, "=> index_read( \"%s\" \"%c\" \"%s\" )\n",
132 attr_masks( be->be_private, type, &indexmask, &syntax );
133 if ( ! (indextype & indexmask) ) {
134 idl = idl_allids( be );
135 Debug( LDAP_DEBUG_TRACE,
136 "<= index_read %ld candidates (allids - not indexed)\n",
137 idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
141 attr_normalize( type );
142 at_cn = at_canonical_name( type );
144 if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_WRCREAT ))
146 Debug( LDAP_DEBUG_ANY,
147 "<= index_read NULL (could not open %s%s)\n", at_cn,
154 if ( prefix != UNKNOWN_PREFIX ) {
155 unsigned int len = strlen( val );
157 if ( (len + 2) < sizeof(buf) ) {
160 /* value + prefix + null */
161 tmpval = (char *) ch_malloc( len + 2 );
165 strcpy( &realval[1], val );
169 key.dsize = strlen( realval ) + 1;
171 idl = idl_fetch( be, db, key );
172 if ( tmpval != NULL ) {
176 ldbm_cache_close( be, db );
178 Debug( LDAP_DEBUG_TRACE, "<= index_read %ld candidates\n",
179 idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
183 /* Remove values from index files */
198 }/* static int delete_value() */
212 /* XXX do we need idl ??? */
213 ID_BLOCK *idl = NULL;
218 char prefix = index2prefix( indextype );
220 ldbm_datum_init( key );
222 Debug( LDAP_DEBUG_TRACE, "=> add_value( \"%c%s\" )\n", prefix, val, 0 );
224 if ( prefix != UNKNOWN_PREFIX ) {
225 unsigned int len = strlen( val );
227 if ( (len + 2) < sizeof(buf) ) {
230 /* value + prefix + null */
231 tmpval = (char *) ch_malloc( len + 2 );
235 strcpy( &realval[1], val );
239 key.dsize = strlen( realval ) + 1;
241 rc = idl_insert_key( be, db, key, id );
243 if ( tmpval != NULL ) {
251 ldap_pvt_thread_yield();
253 /* Debug( LDAP_DEBUG_TRACE, "<= add_value %d\n", rc, 0, 0 ); */
257 /* Remove entries from index files */
263 struct berval **vals,
267 int indexmask, syntax;
268 char *at_cn; /* Attribute canonical name */
270 char *val, *p, *code, *w;
272 char buf[SUBLEN + 1];
277 Debug( LDAP_DEBUG_TRACE,
278 "=> index_delete_values( \"%s\", %ld )\n",
279 (type ? type : "(NULL)"),
283 attr_normalize(type);
284 attr_masks( be->be_private, type, &indexmask, &syntax );
286 if ( indexmask == 0 ) {
290 at_cn = at_canonical_name( type );
292 if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_WRITER ))
295 Debug( LDAP_DEBUG_ANY,
296 "<= index_delete_values -1 (could not open(wr) %s%s)\n",
304 /* Remove each value from index file */
306 for ( i = 0; vals[i] != NULL; i++ ) {
309 * Presence index entry
312 if ( indexmask & INDEX_PRESENCE ) {
313 delete_value( be, db, at_cn, INDEX_PRESENCE, "*", id );
316 Debug( LDAP_DEBUG_TRACE,
317 "*** index_add_values syntax 0x%x syntax bin 0x%x\n",
318 syntax, SYNTAX_BIN, 0 );
320 if ( syntax & SYNTAX_BIN ) {
321 ldbm_cache_close( be, db );
326 len = vals[i]->bv_len;
329 if ( len + 2 > sizeof(vbuf) ) {
331 bigbuf = (char *) ch_malloc( len + 1 );
340 (void) memcpy( val, vals[i]->bv_val, len );
343 value_normalize( val, syntax );
345 /* value_normalize could change the length of val */
350 * equality index entry
353 if ( indexmask & INDEX_EQUALITY ) {
355 delete_value( be, db, at_cn, INDEX_EQUALITY, val, id );
360 * approximate index entry
362 if ( indexmask & INDEX_APPROX ) {
364 for ( w = first_word( val );
366 w = next_word( w ) ) {
368 if ( (code = phonetic( w )) != NULL ) {
383 * substrings index entry
386 if ( indexmask & INDEX_SUB ) {
388 /* leading and trailing */
389 if ( len > SUBLEN - 2 ) {
392 for ( j = 0; j < SUBLEN - 1; j++ ) {
404 p = val + len - SUBLEN + 1;
405 for ( j = 0; j < SUBLEN - 1; j++ ) {
408 buf[SUBLEN - 1] = '$';
422 for (p = val; p < (val + len - SUBLEN + 1); p++) {
424 for ( j = 0; j < SUBLEN; j++ ) {
435 }/* for (p = val; p < (val + len - SUBLEN + 1); p++) */
437 }/* if ( indexmask & INDEX_SUB ) */
439 if ( bigbuf != NULL ) {
445 }/* for ( i = 0; vals[i] != NULL; i++ ) */
447 ldbm_cache_close( be, db );
457 struct berval **vals,
461 char *val, *p, *code, *w;
463 int indexmask, syntax;
464 char buf[SUBLEN + 1];
469 char *at_cn; /* Attribute canonical name */
471 Debug( LDAP_DEBUG_TRACE, "=> index_add_values( \"%s\", %ld )\n", type,
473 attr_normalize(type);
474 attr_masks( be->be_private, type, &indexmask, &syntax );
475 if ( indexmask == 0 ) {
478 at_cn = at_canonical_name( type );
479 if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_WRCREAT ))
481 Debug( LDAP_DEBUG_ANY,
482 "<= index_add_values -1 (could not open/create %s%s)\n",
483 at_cn, LDBM_SUFFIX, 0 );
488 for ( i = 0; vals[i] != NULL; i++ ) {
490 * presence index entry
492 if ( indexmask & INDEX_PRESENCE ) {
493 add_value( be, db, at_cn, INDEX_PRESENCE, "*", id );
496 Debug( LDAP_DEBUG_TRACE, "*** index_add_values syntax 0x%x syntax bin 0x%x\n",
497 syntax, SYNTAX_BIN, 0 );
498 if ( syntax & SYNTAX_BIN ) {
499 ldbm_cache_close( be, db );
504 len = vals[i]->bv_len;
507 if ( len + 2 > sizeof(vbuf) ) {
508 bigbuf = (char *) ch_malloc( len + 1 );
513 (void) memcpy( val, vals[i]->bv_val, len );
516 value_normalize( val, syntax );
518 /* value_normalize could change the length of val */
522 * equality index entry
524 if ( indexmask & INDEX_EQUALITY ) {
525 add_value( be, db, at_cn, INDEX_EQUALITY, val, id );
529 * approximate index entry
531 if ( indexmask & INDEX_APPROX ) {
532 for ( w = first_word( val ); w != NULL;
533 w = next_word( w ) ) {
534 if ( (code = phonetic( w )) != NULL ) {
535 add_value( be, db, at_cn, INDEX_APPROX,
543 * substrings index entry
545 if ( indexmask & INDEX_SUB ) {
546 /* leading and trailing */
547 if ( len > SUBLEN - 2 ) {
549 for ( j = 0; j < SUBLEN - 1; j++ ) {
554 add_value( be, db, at_cn, INDEX_SUB, buf, id );
556 p = val + len - SUBLEN + 1;
557 for ( j = 0; j < SUBLEN - 1; j++ ) {
560 buf[SUBLEN - 1] = '$';
563 add_value( be, db, at_cn, INDEX_SUB, buf, id );
567 for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
568 for ( j = 0; j < SUBLEN; j++ ) {
573 add_value( be, db, at_cn, INDEX_SUB, buf, id );
577 if ( bigbuf != NULL ) {
581 ldbm_cache_close( be, db );
587 index2prefix( int indextype )
591 switch ( indextype ) {
596 prefix = APPROX_PREFIX;
602 prefix = UNKNOWN_PREFIX;