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 /* XXX do we need idl ??? */
199 ID_BLOCK *idl = NULL;
204 char prefix = index2prefix( indextype );
206 ldbm_datum_init( key );
208 Debug( LDAP_DEBUG_TRACE,
209 "=> delete_value( \"%c%s\" )\n",
212 if ( prefix != UNKNOWN_PREFIX ) {
213 unsigned int len = strlen( val );
215 if ( (len + 2) < sizeof(buf) ) {
218 /* value + prefix + null */
219 tmpval = (char *) ch_malloc( len + 2 );
223 strcpy( &realval[1], val );
227 key.dsize = strlen( realval ) + 1;
229 rc = idl_delete_key( be, db, key, id );
231 if ( tmpval != NULL ) {
239 ldap_pvt_thread_yield();
241 Debug( LDAP_DEBUG_TRACE, "<= delete_value %d\n", rc, 0, 0 );
245 }/* static int delete_value() */
259 /* XXX do we need idl ??? */
260 ID_BLOCK *idl = NULL;
265 char prefix = index2prefix( indextype );
267 ldbm_datum_init( key );
269 Debug( LDAP_DEBUG_TRACE, "=> add_value( \"%c%s\" )\n", prefix, val, 0 );
271 if ( prefix != UNKNOWN_PREFIX ) {
272 unsigned int len = strlen( val );
274 if ( (len + 2) < sizeof(buf) ) {
277 /* value + prefix + null */
278 tmpval = (char *) ch_malloc( len + 2 );
282 strcpy( &realval[1], val );
286 key.dsize = strlen( realval ) + 1;
288 rc = idl_insert_key( be, db, key, id );
290 if ( tmpval != NULL ) {
298 ldap_pvt_thread_yield();
300 /* Debug( LDAP_DEBUG_TRACE, "<= add_value %d\n", rc, 0, 0 ); */
304 /* Remove entries from index files */
310 struct berval **vals,
314 int indexmask, syntax;
315 char *at_cn; /* Attribute canonical name */
317 char *val, *p, *code, *w;
319 char buf[SUBLEN + 1];
324 Debug( LDAP_DEBUG_TRACE,
325 "=> index_delete_values( \"%s\", %ld )\n",
326 (type ? type : "(NULL)"),
330 attr_normalize(type);
331 attr_masks( be->be_private, type, &indexmask, &syntax );
333 if ( indexmask == 0 ) {
337 at_cn = at_canonical_name( type );
339 if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_WRITER ))
342 Debug( LDAP_DEBUG_ANY,
343 "<= index_delete_values -1 (could not open(wr) %s%s)\n",
351 /* Remove each value from index file */
353 for ( i = 0; vals[i] != NULL; i++ ) {
356 * Presence index entry
359 if ( indexmask & INDEX_PRESENCE ) {
360 delete_value( be, db, at_cn, INDEX_PRESENCE, "*", id );
363 Debug( LDAP_DEBUG_TRACE,
364 "*** index_add_values syntax 0x%x syntax bin 0x%x\n",
365 syntax, SYNTAX_BIN, 0 );
367 if ( syntax & SYNTAX_BIN ) {
368 ldbm_cache_close( be, db );
373 len = vals[i]->bv_len;
376 if ( len + 2 > sizeof(vbuf) ) {
378 bigbuf = (char *) ch_malloc( len + 1 );
387 (void) memcpy( val, vals[i]->bv_val, len );
390 value_normalize( val, syntax );
392 /* value_normalize could change the length of val */
397 * equality index entry
400 if ( indexmask & INDEX_EQUALITY ) {
402 delete_value( be, db, at_cn, INDEX_EQUALITY, val, id );
407 * approximate index entry
409 if ( indexmask & INDEX_APPROX ) {
411 for ( w = first_word( val );
413 w = next_word( w ) ) {
415 if ( (code = phonetic( w )) != NULL ) {
430 * substrings index entry
433 if ( indexmask & INDEX_SUB ) {
435 /* leading and trailing */
436 if ( len > SUBLEN - 2 ) {
439 for ( j = 0; j < SUBLEN - 1; j++ ) {
451 p = val + len - SUBLEN + 1;
452 for ( j = 0; j < SUBLEN - 1; j++ ) {
455 buf[SUBLEN - 1] = '$';
469 for (p = val; p < (val + len - SUBLEN + 1); p++) {
471 for ( j = 0; j < SUBLEN; j++ ) {
482 }/* for (p = val; p < (val + len - SUBLEN + 1); p++) */
484 }/* if ( indexmask & INDEX_SUB ) */
486 if ( bigbuf != NULL ) {
492 }/* for ( i = 0; vals[i] != NULL; i++ ) */
494 ldbm_cache_close( be, db );
504 struct berval **vals,
508 char *val, *p, *code, *w;
510 int indexmask, syntax;
511 char buf[SUBLEN + 1];
516 char *at_cn; /* Attribute canonical name */
518 Debug( LDAP_DEBUG_TRACE, "=> index_add_values( \"%s\", %ld )\n", type,
520 attr_normalize(type);
521 attr_masks( be->be_private, type, &indexmask, &syntax );
522 if ( indexmask == 0 ) {
525 at_cn = at_canonical_name( type );
526 if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_WRCREAT ))
528 Debug( LDAP_DEBUG_ANY,
529 "<= index_add_values -1 (could not open/create %s%s)\n",
530 at_cn, LDBM_SUFFIX, 0 );
535 for ( i = 0; vals[i] != NULL; i++ ) {
537 * presence index entry
539 if ( indexmask & INDEX_PRESENCE ) {
540 add_value( be, db, at_cn, INDEX_PRESENCE, "*", id );
543 Debug( LDAP_DEBUG_TRACE, "*** index_add_values syntax 0x%x syntax bin 0x%x\n",
544 syntax, SYNTAX_BIN, 0 );
545 if ( syntax & SYNTAX_BIN ) {
546 ldbm_cache_close( be, db );
551 len = vals[i]->bv_len;
554 if ( len + 2 > sizeof(vbuf) ) {
555 bigbuf = (char *) ch_malloc( len + 1 );
560 (void) memcpy( val, vals[i]->bv_val, len );
563 value_normalize( val, syntax );
565 /* value_normalize could change the length of val */
569 * equality index entry
571 if ( indexmask & INDEX_EQUALITY ) {
572 add_value( be, db, at_cn, INDEX_EQUALITY, val, id );
576 * approximate index entry
578 if ( indexmask & INDEX_APPROX ) {
579 for ( w = first_word( val ); w != NULL;
580 w = next_word( w ) ) {
581 if ( (code = phonetic( w )) != NULL ) {
582 add_value( be, db, at_cn, INDEX_APPROX,
590 * substrings index entry
592 if ( indexmask & INDEX_SUB ) {
593 /* leading and trailing */
594 if ( len > SUBLEN - 2 ) {
596 for ( j = 0; j < SUBLEN - 1; j++ ) {
601 add_value( be, db, at_cn, INDEX_SUB, buf, id );
603 p = val + len - SUBLEN + 1;
604 for ( j = 0; j < SUBLEN - 1; j++ ) {
607 buf[SUBLEN - 1] = '$';
610 add_value( be, db, at_cn, INDEX_SUB, buf, id );
614 for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
615 for ( j = 0; j < SUBLEN; j++ ) {
620 add_value( be, db, at_cn, INDEX_SUB, buf, id );
624 if ( bigbuf != NULL ) {
628 ldbm_cache_close( be, db );
634 index2prefix( int indextype )
638 switch ( indextype ) {
643 prefix = APPROX_PREFIX;
649 prefix = UNKNOWN_PREFIX;