1 /* index.c - routines for dealing with attribute indexes */
12 #include "back-bdb2.h"
14 static int add_value(BackendDB *be, struct dbcache *db, char *type, int indextype, char *val, ID id);
15 static int index2prefix(int indextype);
18 bdb2i_index_add_entry(
25 struct berval *bvals[2];
27 Debug( LDAP_DEBUG_TRACE, "=> index_add( %ld, \"%s\" )\n", e->e_id,
31 * dn index entry - make it look like an attribute so it works
32 * with bdb2i_index_add_values() call
35 bv.bv_val = ch_strdup( e->e_ndn );
36 bv.bv_len = strlen( bv.bv_val );
40 /* add the dn to the indexes */
42 char *dn = ch_strdup( "dn" );
43 bdb2i_index_add_values( be, dn, bvals, e->e_id );
49 /* add each attribute to the indexes */
50 for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
51 bdb2i_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 ) {
73 case LDAP_MOD_REPLACE:
74 rc = bdb2i_index_add_values( be, mod->mod_type,
75 mod->mod_bvalues, id );
77 case LDAP_MOD_SOFTADD:
102 int indexmask, syntax;
104 char *realval, *tmpval;
109 ldbm_datum_init( key );
111 prefix = index2prefix( indextype );
112 Debug( LDAP_DEBUG_TRACE, "=> bdb2i_index_read( \"%c%s\" -> \"%s\" )\n",
115 bdb2i_attr_masks( be->be_private, type, &indexmask, &syntax );
116 if ( ! (indextype & indexmask) ) {
117 idl = bdb2i_idl_allids( be );
118 Debug( LDAP_DEBUG_TRACE,
119 "<= bdb2i_index_read %ld candidates (allids - not indexed)\n",
120 idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
124 attr_normalize( type );
125 at_cn = at_canonical_name(type);
127 if ( at_cn == NULL ) {
128 Debug( LDAP_DEBUG_ANY,
129 "<= bdb2i_index_read no canonical name for type \"%s\"\n",
130 type != NULL ? type : "(NULL)", 0, 0 );
134 if ( (db = bdb2i_cache_open( be, at_cn, BDB2_SUFFIX, LDBM_WRCREAT ))
136 Debug( LDAP_DEBUG_ANY,
137 "<= bdb2i_index_read NULL (could not open %s%s)\n", at_cn,
144 if ( prefix != UNKNOWN_PREFIX ) {
145 unsigned int len = strlen( val );
147 if ( (len + 2) < sizeof(buf) ) {
150 /* value + prefix + null */
151 tmpval = (char *) ch_malloc( len + 2 );
156 strcpy( &realval[1], val );
160 key.dsize = strlen( realval ) + 1;
162 idl = bdb2i_idl_fetch( be, db, key );
163 if ( tmpval != NULL ) {
167 bdb2i_cache_close( be, db );
169 Debug( LDAP_DEBUG_TRACE, "<= bdb2i_index_read %ld candidates\n",
170 idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
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 = bdb2i_idl_insert_key( be, db, key, id );
215 if ( tmpval != NULL ) {
219 ldap_pvt_thread_yield();
221 /* Debug( LDAP_DEBUG_TRACE, "<= add_value %d\n", rc, 0, 0 ); */
226 bdb2i_index_add_values(
229 struct berval **vals,
233 char *val, *p, *code, *w;
235 int indexmask, syntax;
236 char buf[SUBLEN + 1];
244 Debug( LDAP_DEBUG_TRACE,
245 "=> bdb2i_index_add_values( \"%s\", NULL, %ld )\n",
250 Debug( LDAP_DEBUG_TRACE, "=> bdb2i_index_add_values( \"%s\", %ld )\n",
252 attr_normalize( type );
253 bdb2i_attr_masks( be->be_private, type, &indexmask, &syntax );
254 if ( indexmask == 0 ) {
258 at_cn = at_canonical_name(type);
260 if ( at_cn == NULL ) {
261 Debug( LDAP_DEBUG_ANY,
262 "<= bdb2i_index_add_values no canonical name for type \"%s\"\n",
263 type != NULL ? type : "(NULL)", 0, 0 );
267 if ( (db = bdb2i_cache_open( be, at_cn, BDB2_SUFFIX, LDBM_WRCREAT ))
269 Debug( LDAP_DEBUG_ANY,
270 "<= bdb2i_index_add_values -1 (could not open/create %s%s)\n",
271 at_cn, BDB2_SUFFIX, 0 );
275 for ( i = 0; vals[i] != NULL; i++ ) {
277 * presence index entry
279 if ( indexmask & INDEX_PRESENCE ) {
280 add_value( be, db, at_cn, INDEX_PRESENCE, "*", id );
283 Debug( LDAP_DEBUG_TRACE, "*** bdb2i_index_add_values syntax 0x%x syntax bin 0x%x\n",
284 syntax, SYNTAX_BIN, 0 );
285 if ( syntax & SYNTAX_BIN ) {
286 bdb2i_cache_close( be, db );
291 len = vals[i]->bv_len;
294 if ( len + 2 > sizeof(vbuf) ) {
295 bigbuf = (char *) ch_malloc( len + 1 );
300 (void) memcpy( val, vals[i]->bv_val, len );
303 value_normalize( val, syntax );
305 /* value_normalize could change the length of val */
309 * equality index entry
311 if ( indexmask & INDEX_EQUALITY ) {
312 add_value( be, db, at_cn, INDEX_EQUALITY, val, id );
316 * approximate index entry
318 if ( indexmask & INDEX_APPROX ) {
319 for ( w = first_word( val ); w != NULL;
320 w = next_word( w ) ) {
321 if ( (code = phonetic( w )) != NULL ) {
322 add_value( be, db, at_cn, INDEX_APPROX,
330 * substrings index entry
332 if ( indexmask & INDEX_SUB ) {
333 /* leading and trailing */
334 if ( len > SUBLEN - 2 ) {
336 for ( j = 0; j < SUBLEN - 1; j++ ) {
341 add_value( be, db, at_cn, INDEX_SUB, buf, id );
343 p = val + len - SUBLEN + 1;
344 for ( j = 0; j < SUBLEN - 1; j++ ) {
347 buf[SUBLEN - 1] = '$';
350 add_value( be, db, at_cn, INDEX_SUB, buf, id );
354 for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
355 for ( j = 0; j < SUBLEN; j++ ) {
360 add_value( be, db, at_cn, INDEX_SUB, buf, id );
364 if ( bigbuf != NULL ) {
368 bdb2i_cache_close( be, db );
374 index2prefix( int indextype )
378 switch ( indextype ) {
383 prefix = APPROX_PREFIX;
389 prefix = UNKNOWN_PREFIX;