1 /* index.c - routines for dealing with attribute indexes */
11 #include "back-ldbm.h"
13 static int add_value(Backend *be, struct dbcache *db, char *type, int indextype, char *val, ID id);
14 static int index2prefix(int indextype);
24 struct berval *bvals[2];
26 Debug( LDAP_DEBUG_TRACE, "=> index_add( %ld, \"%s\" )\n", e->e_id,
30 * dn index entry - make it look like an attribute so it works
31 * with index_add_values() call
34 bv.bv_val = ch_strdup( e->e_ndn );
35 bv.bv_len = strlen( bv.bv_val );
39 /* add the dn to the indexes */
41 char *dn = ch_strdup("dn");
42 index_add_values( be, dn, bvals, e->e_id );
48 /* add each attribute to the indexes */
49 for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
51 index_add_values( be, ap->a_type, ap->a_vals, e->e_id );
54 Debug( LDAP_DEBUG_TRACE, "<= index_add( %ld, \"%s\" ) 0\n", e->e_id,
68 for ( ; ml != NULL; ml = ml->ml_next ) {
69 LDAPMod *mod = &ml->ml_mod;
71 switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) {
72 case LDAP_MOD_REPLACE:
73 /* XXX: Delete old index data==>problem when this
74 * gets called we lost values already!
77 rc = index_add_values( be, mod->mod_type,
78 mod->mod_bvalues, id );
81 rc = index_delete_values( be, mod->mod_type,
82 mod->mod_bvalues, id );
84 case LDAP_MOD_SOFTADD: /* SOFTADD means index was there */
108 int indexmask, syntax;
110 char *realval, *tmpval;
115 ldbm_datum_init( key );
117 prefix = index2prefix( indextype );
118 Debug( LDAP_DEBUG_TRACE, "=> index_read( \"%s\" \"%c\" \"%s\" )\n",
121 attr_masks( be->be_private, type, &indexmask, &syntax );
122 if ( ! (indextype & indexmask) ) {
123 idl = idl_allids( be );
124 Debug( LDAP_DEBUG_TRACE,
125 "<= index_read %ld candidates (allids - not indexed)\n",
126 idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
130 attr_normalize( type );
131 at_cn = at_canonical_name( type );
133 if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_WRCREAT ))
135 Debug( LDAP_DEBUG_ANY,
136 "<= index_read NULL (could not open %s%s)\n", at_cn,
143 if ( prefix != UNKNOWN_PREFIX ) {
144 unsigned int len = strlen( val );
146 if ( (len + 2) < sizeof(buf) ) {
149 /* value + prefix + null */
150 tmpval = (char *) ch_malloc( len + 2 );
154 strcpy( &realval[1], val );
158 key.dsize = strlen( realval ) + 1;
160 idl = idl_fetch( be, db, key );
161 if ( tmpval != NULL ) {
165 ldbm_cache_close( be, db );
167 Debug( LDAP_DEBUG_TRACE, "<= index_read %ld candidates\n",
168 idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
184 /* XXX do we need idl ??? */
185 ID_BLOCK *idl = NULL;
190 char prefix = index2prefix( indextype );
192 ldbm_datum_init( key );
194 Debug( LDAP_DEBUG_TRACE, "=> add_value( \"%c%s\" )\n", prefix, val, 0 );
196 if ( prefix != UNKNOWN_PREFIX ) {
197 unsigned int len = strlen( val );
199 if ( (len + 2) < sizeof(buf) ) {
202 /* value + prefix + null */
203 tmpval = (char *) ch_malloc( len + 2 );
207 strcpy( &realval[1], val );
211 key.dsize = strlen( realval ) + 1;
213 rc = idl_insert_key( be, db, key, id );
215 if ( tmpval != NULL ) {
223 ldap_pvt_thread_yield();
225 /* Debug( LDAP_DEBUG_TRACE, "<= add_value %d\n", rc, 0, 0 ); */
229 /* Remove entries from index files */
235 struct berval **vals,
248 struct berval **vals,
252 char *val, *p, *code, *w;
254 int indexmask, syntax;
255 char buf[SUBLEN + 1];
260 char *at_cn; /* Attribute canonical name */
262 Debug( LDAP_DEBUG_TRACE, "=> index_add_values( \"%s\", %ld )\n", type,
264 attr_normalize(type);
265 attr_masks( be->be_private, type, &indexmask, &syntax );
266 if ( indexmask == 0 ) {
269 at_cn = at_canonical_name( type );
270 if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_WRCREAT ))
272 Debug( LDAP_DEBUG_ANY,
273 "<= index_add_values -1 (could not open/create %s%s)\n",
274 at_cn, LDBM_SUFFIX, 0 );
279 for ( i = 0; vals[i] != NULL; i++ ) {
281 * presence index entry
283 if ( indexmask & INDEX_PRESENCE ) {
284 add_value( be, db, at_cn, INDEX_PRESENCE, "*", id );
287 Debug( LDAP_DEBUG_TRACE, "*** index_add_values syntax 0x%x syntax bin 0x%x\n",
288 syntax, SYNTAX_BIN, 0 );
289 if ( syntax & SYNTAX_BIN ) {
290 ldbm_cache_close( be, db );
295 len = vals[i]->bv_len;
298 if ( len + 2 > sizeof(vbuf) ) {
299 bigbuf = (char *) ch_malloc( len + 1 );
304 (void) memcpy( val, vals[i]->bv_val, len );
307 value_normalize( val, syntax );
309 /* value_normalize could change the length of val */
313 * equality index entry
315 if ( indexmask & INDEX_EQUALITY ) {
316 add_value( be, db, at_cn, INDEX_EQUALITY, val, id );
320 * approximate index entry
322 if ( indexmask & INDEX_APPROX ) {
323 for ( w = first_word( val ); w != NULL;
324 w = next_word( w ) ) {
325 if ( (code = phonetic( w )) != NULL ) {
326 add_value( be, db, at_cn, INDEX_APPROX,
334 * substrings index entry
336 if ( indexmask & INDEX_SUB ) {
337 /* leading and trailing */
338 if ( len > SUBLEN - 2 ) {
340 for ( j = 0; j < SUBLEN - 1; j++ ) {
345 add_value( be, db, at_cn, INDEX_SUB, buf, id );
347 p = val + len - SUBLEN + 1;
348 for ( j = 0; j < SUBLEN - 1; j++ ) {
351 buf[SUBLEN - 1] = '$';
354 add_value( be, db, at_cn, INDEX_SUB, buf, id );
358 for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
359 for ( j = 0; j < SUBLEN; j++ ) {
364 add_value( be, db, at_cn, INDEX_SUB, buf, id );
368 if ( bigbuf != NULL ) {
372 ldbm_cache_close( be, db );
378 index2prefix( int indextype )
382 switch ( indextype ) {
387 prefix = APPROX_PREFIX;
393 prefix = UNKNOWN_PREFIX;