1 /* index.c - routines for dealing with attribute indexes */
11 #include "back-bdb2.h"
13 static int add_value(BackendDB *be, struct dbcache *db, char *type, int indextype, char *val, ID id);
14 static int index2prefix(int indextype);
17 bdb2i_index_add_entry(
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 bdb2i_index_add_values() call
34 bv.bv_val = ch_strdup( e->e_dn );
35 bv.bv_len = strlen( bv.bv_val );
36 (void) dn_normalize_case( bv.bv_val );
40 /* add the dn to the indexes */
41 bdb2i_index_add_values( be, "dn", bvals, e->e_id );
45 /* add each attribute to the indexes */
46 for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
47 bdb2i_index_add_values( be, ap->a_type, ap->a_vals, e->e_id );
50 Debug( LDAP_DEBUG_TRACE, "<= index_add( %ld, \"%s\" ) 0\n", e->e_id,
64 for ( ; ml != NULL; ml = ml->ml_next ) {
65 LDAPMod *mod = &ml->ml_mod;
67 switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) {
69 case LDAP_MOD_REPLACE:
70 rc = bdb2i_index_add_values( be, mod->mod_type,
71 mod->mod_bvalues, id );
98 int indexmask, syntax;
100 char *realval, *tmpval;
103 ldbm_datum_init( key );
105 prefix = index2prefix( indextype );
106 Debug( LDAP_DEBUG_TRACE, "=> bdb2i_index_read( \"%s\" \"%c\" \"%s\" )\n",
109 bdb2i_attr_masks( be->be_private, type, &indexmask, &syntax );
110 if ( ! (indextype & indexmask) ) {
111 idl = bdb2i_idl_allids( be );
112 Debug( LDAP_DEBUG_TRACE,
113 "<= bdb2i_index_read %ld candidates (allids - not indexed)\n",
114 idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
118 attr_normalize( type );
119 if ( (db = bdb2i_cache_open( be, type, BDB2_SUFFIX, LDBM_WRCREAT ))
121 Debug( LDAP_DEBUG_ANY,
122 "<= bdb2i_index_read NULL (could not open %s%s)\n", type,
129 if ( prefix != UNKNOWN_PREFIX ) {
130 unsigned int len = strlen( val );
132 if ( (len + 2) < sizeof(buf) ) {
135 /* value + prefix + null */
136 tmpval = (char *) ch_malloc( len + 2 );
140 strcpy( &realval[1], val );
144 key.dsize = strlen( realval ) + 1;
146 idl = bdb2i_idl_fetch( be, db, key );
147 if ( tmpval != NULL ) {
151 bdb2i_cache_close( be, db );
153 Debug( LDAP_DEBUG_TRACE, "<= bdb2i_index_read %ld candidates\n",
154 idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
174 char prefix = index2prefix( indextype );
176 ldbm_datum_init( key );
178 Debug( LDAP_DEBUG_TRACE, "=> add_value( \"%c%s\" )\n", prefix, val, 0 );
180 if ( prefix != UNKNOWN_PREFIX ) {
181 unsigned int len = strlen( val );
183 if ( (len + 2) < sizeof(buf) ) {
186 /* value + prefix + null */
187 tmpval = (char *) ch_malloc( len + 2 );
191 strcpy( &realval[1], val );
195 key.dsize = strlen( realval ) + 1;
197 rc = bdb2i_idl_insert_key( be, db, key, id );
199 if ( tmpval != NULL ) {
203 ldap_pvt_thread_yield();
205 /* Debug( LDAP_DEBUG_TRACE, "<= add_value %d\n", rc, 0, 0 ); */
210 bdb2i_index_add_values(
213 struct berval **vals,
217 char *val, *p, *code, *w;
219 int indexmask, syntax;
220 char buf[SUBLEN + 1];
225 Debug( LDAP_DEBUG_TRACE, "=> bdb2i_index_add_values( \"%s\", %ld )\n", type,
228 bdb2i_attr_masks( be->be_private, type, &indexmask, &syntax );
229 if ( indexmask == 0 ) {
233 if ( (db = bdb2i_cache_open( be, type, BDB2_SUFFIX, LDBM_WRCREAT ))
235 Debug( LDAP_DEBUG_ANY,
236 "<= bdb2i_index_add_values -1 (could not open/create %s%s)\n",
237 type, BDB2_SUFFIX, 0 );
241 for ( i = 0; vals[i] != NULL; i++ ) {
243 * presence index entry
245 if ( indexmask & INDEX_PRESENCE ) {
246 add_value( be, db, type, INDEX_PRESENCE, "*", id );
249 Debug( LDAP_DEBUG_TRACE, "*** bdb2i_index_add_values syntax 0x%x syntax bin 0x%x\n",
250 syntax, SYNTAX_BIN, 0 );
251 if ( syntax & SYNTAX_BIN ) {
252 bdb2i_cache_close( be, db );
257 len = vals[i]->bv_len;
260 if ( len + 2 > sizeof(vbuf) ) {
261 bigbuf = (char *) ch_malloc( len + 1 );
266 (void) memcpy( val, vals[i]->bv_val, len );
269 value_normalize( val, syntax );
272 * equality index entry
274 if ( indexmask & INDEX_EQUALITY ) {
275 add_value( be, db, type, INDEX_EQUALITY, val, id );
279 * approximate index entry
281 if ( indexmask & INDEX_APPROX ) {
282 for ( w = first_word( val ); w != NULL;
283 w = next_word( w ) ) {
284 if ( (code = phonetic( w )) != NULL ) {
285 add_value( be, db, type, INDEX_APPROX,
293 * substrings index entry
295 if ( indexmask & INDEX_SUB ) {
296 /* leading and trailing */
297 if ( len > SUBLEN - 2 ) {
299 for ( j = 0; j < SUBLEN - 1; j++ ) {
304 add_value( be, db, type, INDEX_SUB, buf, id );
306 p = val + len - SUBLEN + 1;
307 for ( j = 0; j < SUBLEN - 1; j++ ) {
310 buf[SUBLEN - 1] = '$';
313 add_value( be, db, type, INDEX_SUB, buf, id );
317 for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
318 for ( j = 0; j < SUBLEN; j++ ) {
323 add_value( be, db, type, INDEX_SUB, buf, id );
327 if ( bigbuf != NULL ) {
331 bdb2i_cache_close( be, db );
337 index2prefix( int indextype )
341 switch ( indextype ) {
346 prefix = APPROX_PREFIX;
352 prefix = UNKNOWN_PREFIX;