1 /* index.c - routines for dealing with attribute indexes */
3 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
11 #include <ac/string.h>
12 #include <ac/socket.h>
15 #include "back-ldbm.h"
17 static int change_value(Backend *be,
24 (*idl_func)(Backend *, DBCache *, Datum, ID));
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_change_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_change_values( be, dn, bvals, e->e_id, SLAP_INDEX_ADD_OP );
59 /* add each attribute to the indexes */
60 for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
61 index_change_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_change_values( be,
95 rc = index_change_values( be,
99 SLAP_INDEX_DELETE_OP );
101 case LDAP_MOD_SOFTADD: /* SOFTADD means index was there */
125 int indexmask, syntax;
127 char *realval, *tmpval;
132 ldbm_datum_init( key );
134 prefix = index2prefix( indextype );
135 Debug( LDAP_DEBUG_TRACE, "=> index_read(\"%c%s\"->\"%s\")\n",
138 attr_masks( be->be_private, type, &indexmask, &syntax );
139 if ( ! (indextype & indexmask) ) {
140 idl = idl_allids( be );
141 Debug( LDAP_DEBUG_TRACE,
142 "<= index_read %ld candidates (allids - not indexed)\n",
143 idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
147 attr_normalize( type );
148 at_cn = at_canonical_name( type );
150 if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_WRCREAT ))
152 Debug( LDAP_DEBUG_ANY,
153 "<= index_read NULL (could not open %s%s)\n", at_cn,
160 if ( prefix != UNKNOWN_PREFIX ) {
161 unsigned int len = strlen( val );
163 if ( (len + 2) < sizeof(buf) ) {
166 /* value + prefix + null */
167 tmpval = (char *) ch_malloc( len + 2 );
172 strcpy( &realval[1], val );
176 key.dsize = strlen( realval ) + 1;
178 idl = idl_fetch( be, db, key );
179 if ( tmpval != NULL ) {
183 ldbm_cache_close( be, db );
185 Debug( LDAP_DEBUG_TRACE, "<= index_read %ld candidates\n",
186 idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
190 /* Add or remove stuff from index files */
200 int (*idl_func)(Backend *, DBCache *, Datum, ID)
209 char prefix = index2prefix( indextype );
211 ldbm_datum_init( key );
213 Debug( LDAP_DEBUG_TRACE,
214 "=> change_value( \"%c%s\", op=%s )\n",
215 prefix, val, (idl_func == idl_insert_key ? "ADD":"DELETE") );
217 if ( prefix != UNKNOWN_PREFIX ) {
218 unsigned int len = strlen( val );
220 if ( (len + 2) < sizeof(buf) ) {
223 /* value + prefix + null */
224 tmpval = (char *) ch_malloc( len + 2 );
228 strcpy( &realval[1], val );
232 key.dsize = strlen( realval ) + 1;
234 rc = idl_func( be, db, key, id );
236 if ( tmpval != NULL ) {
240 ldap_pvt_thread_yield();
242 Debug( LDAP_DEBUG_TRACE, "<= change_value %d\n", rc, 0, 0 );
246 }/* static int change_value() */
253 struct berval **vals,
258 char *val, *p, *code, *w;
260 int indexmask, syntax;
261 char buf[SUBLEN + 1];
266 int (*idl_funct)(Backend *,
269 char *at_cn; /* Attribute canonical name */
273 Debug( LDAP_DEBUG_TRACE,
274 "=> index_change_values( %s, NULL, %ld, op=%s )\n",
275 type, id, ((op == SLAP_INDEX_ADD_OP) ? "ADD" : "DELETE" ) );
279 Debug( LDAP_DEBUG_TRACE,
280 "=> index_change_values( \"%s\", %ld, op=%s )\n",
281 type, id, ((op == SLAP_INDEX_ADD_OP) ? "ADD" : "DELETE" ) );
284 if (op == SLAP_INDEX_ADD_OP) {
288 idl_funct = idl_insert_key;
295 idl_funct = idl_delete_key;
300 attr_normalize(type);
301 attr_masks( be->be_private, type, &indexmask, &syntax );
303 if ( indexmask == 0 ) {
307 at_cn = at_canonical_name( type );
309 if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, mode ))
311 Debug( LDAP_DEBUG_ANY,
312 "<= index_change_values (couldn't open(%s%s),md=%s)\n",
315 ((mode==LDBM_WRCREAT)?"LDBM_WRCREAT":"LDBM_WRITER") );
320 for ( i = 0; vals[i] != NULL; i++ ) {
322 * presence index entry
324 if ( indexmask & INDEX_PRESENCE ) {
326 change_value( be, db, at_cn, INDEX_PRESENCE,
327 "*", id, idl_funct );
331 Debug( LDAP_DEBUG_TRACE,
332 "index_change_values syntax 0x%x syntax bin 0x%x\n",
333 syntax, SYNTAX_BIN, 0 );
335 if ( syntax & SYNTAX_BIN ) {
337 ldbm_cache_close( be, db );
343 len = vals[i]->bv_len;
346 if ( len + 2 > sizeof(vbuf) ) {
347 bigbuf = (char *) ch_malloc( len + 1 );
352 (void) memcpy( val, vals[i]->bv_val, len );
355 value_normalize( val, syntax );
357 /* value_normalize could change the length of val */
361 * equality index entry
363 if ( indexmask & INDEX_EQUALITY ) {
365 change_value( be, db, at_cn, INDEX_EQUALITY,
371 * approximate index entry
373 if ( indexmask & INDEX_APPROX ) {
374 for ( w = first_word( val ); w != NULL;
375 w = next_word( w ) ) {
376 if ( (code = phonetic( w )) != NULL ) {
390 * substrings index entry
392 if ( indexmask & INDEX_SUB ) {
393 /* leading and trailing */
394 if ( len > SUBLEN - 2 ) {
396 for ( j = 0; j < SUBLEN - 1; j++ ) {
401 change_value( be, db, at_cn, INDEX_SUB,
402 buf, id, idl_funct );
404 p = val + len - SUBLEN + 1;
405 for ( j = 0; j < SUBLEN - 1; j++ ) {
408 buf[SUBLEN - 1] = '$';
411 change_value( be, db, at_cn, INDEX_SUB,
412 buf, id, idl_funct );
416 for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
417 for ( j = 0; j < SUBLEN; j++ ) {
422 change_value( be, db, at_cn, INDEX_SUB,
423 buf, id, idl_funct );
427 if ( bigbuf != NULL ) {
432 ldbm_cache_close( be, db );
439 index2prefix( int indextype )
443 switch ( indextype ) {
448 prefix = APPROX_PREFIX;
454 prefix = UNKNOWN_PREFIX;