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);
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 index_add_values() call
35 bv.bv_val = ch_strdup( e->e_dn );
36 bv.bv_len = strlen( bv.bv_val );
37 (void) dn_normalize_case( bv.bv_val );
41 /* add the dn to the indexes */
42 index_add_values( be, "dn", bvals, e->e_id );
46 /* add each attribute to the indexes */
47 for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
48 index_add_values( be, ap->a_type, ap->a_vals, e->e_id );
51 Debug( LDAP_DEBUG_TRACE, "<= index_add( %ld, \"%s\" ) 0\n", e->e_id,
65 for ( ; mods != NULL; mods = mods->mod_next ) {
66 switch ( mods->mod_op & ~LDAP_MOD_BVALUES ) {
68 case LDAP_MOD_REPLACE:
69 rc = index_add_values( be, mods->mod_type,
70 mods->mod_bvalues, id );
97 int indexmask, syntax;
99 char *realval, *tmpval;
102 ldbm_datum_init( key );
104 prefix = index2prefix( indextype );
105 Debug( LDAP_DEBUG_TRACE, "=> index_read( \"%s\" \"%c\" \"%s\" )\n",
108 attr_masks( be->be_private, type, &indexmask, &syntax );
109 if ( ! (indextype & indexmask) ) {
110 idl = idl_allids( be );
111 Debug( LDAP_DEBUG_TRACE,
112 "<= index_read %lu candidates (allids - not indexed)\n",
113 idl ? idl->b_nids : 0, 0, 0 );
117 attr_normalize( type );
118 if ( (db = ldbm_cache_open( be, type, LDBM_SUFFIX, LDBM_WRCREAT ))
120 Debug( LDAP_DEBUG_ANY,
121 "<= index_read NULL (could not open %s%s)\n", type,
128 if ( prefix != UNKNOWN_PREFIX ) {
129 unsigned int len = strlen( val );
131 if ( (len + 2) < sizeof(buf) ) {
134 /* value + prefix + null */
135 tmpval = (char *) ch_malloc( len + 2 );
139 strcpy( &realval[1], val );
143 key.dsize = strlen( realval ) + 1;
145 idl = idl_fetch( be, db, key );
146 if ( tmpval != NULL ) {
150 ldbm_cache_close( be, db );
152 Debug( LDAP_DEBUG_TRACE, "<= index_read %lu candidates\n",
153 idl ? idl->b_nids : 0, 0, 0 );
171 char *realval, *tmpval, *s;
174 ldbm_datum_init( key );
176 prefix = index2prefix( indextype );
177 Debug( LDAP_DEBUG_TRACE, "=> add_value( \"%c%s\" )\n", prefix, val, 0 );
182 if ( prefix != UNKNOWN_PREFIX ) {
183 unsigned int len = strlen( val );
185 if ( (len + 2) < sizeof(buf) ) {
188 /* value + prefix + null */
189 tmpval = (char *) ch_malloc( len + 2 );
193 strcpy( &realval[1], val );
197 key.dsize = strlen( realval ) + 1;
199 rc = idl_insert_key( be, db, key, id );
201 if ( tmpval != NULL ) {
208 /* Debug( LDAP_DEBUG_TRACE, "<= add_value %d\n", rc, 0, 0 ); */
216 struct berval **vals,
220 char *val, *p, *code, *w;
222 int indexmask, syntax;
223 char buf[SUBLEN + 1];
228 Debug( LDAP_DEBUG_TRACE, "=> index_add_values( \"%s\", %ld )\n", type,
231 attr_masks( be->be_private, type, &indexmask, &syntax );
232 if ( indexmask == 0 ) {
236 if ( (db = ldbm_cache_open( be, type, LDBM_SUFFIX, LDBM_WRCREAT ))
238 Debug( LDAP_DEBUG_ANY,
239 "<= index_add_values -1 (could not open/create %s%s)\n",
240 type, LDBM_SUFFIX, 0 );
245 for ( i = 0; vals[i] != NULL; i++ ) {
247 * presence index entry
249 if ( indexmask & INDEX_PRESENCE ) {
250 add_value( be, db, type, INDEX_PRESENCE, "*", id );
253 Debug( LDAP_DEBUG_TRACE, "*** index_add_values syntax 0x%x syntax bin 0x%x\n",
254 syntax, SYNTAX_BIN, 0 );
255 if ( syntax & SYNTAX_BIN ) {
256 ldbm_cache_close( be, db );
261 len = vals[i]->bv_len;
264 if ( len + 2 > sizeof(vbuf) ) {
265 bigbuf = (char *) ch_malloc( len + 1 );
270 (void) memcpy( val, vals[i]->bv_val, len );
273 value_normalize( val, syntax );
276 * equality index entry
278 if ( indexmask & INDEX_EQUALITY ) {
279 add_value( be, db, type, INDEX_EQUALITY, val, id );
283 * approximate index entry
285 if ( indexmask & INDEX_APPROX ) {
286 for ( w = first_word( val ); w != NULL;
287 w = next_word( w ) ) {
288 if ( (code = phonetic( w )) != NULL ) {
289 add_value( be, db, type, INDEX_APPROX,
297 * substrings index entry
299 if ( indexmask & INDEX_SUB ) {
300 /* leading and trailing */
301 if ( len > SUBLEN - 2 ) {
303 for ( j = 0; j < SUBLEN - 1; j++ ) {
308 add_value( be, db, type, INDEX_SUB, buf, id );
310 p = val + len - SUBLEN + 1;
311 for ( j = 0; j < SUBLEN - 1; j++ ) {
314 buf[SUBLEN - 1] = '$';
317 add_value( be, db, type, INDEX_SUB, buf, id );
321 for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
322 for ( j = 0; j < SUBLEN; j++ ) {
327 add_value( be, db, type, INDEX_SUB, buf, id );
331 if ( bigbuf != NULL ) {
335 ldbm_cache_close( be, db );
341 index2prefix( int indextype )
345 switch ( indextype ) {
350 prefix = APPROX_PREFIX;
356 prefix = UNKNOWN_PREFIX;