From 32c7186b9c2137708cb88b7c0e1b71dbedf1ab35 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Tue, 22 Aug 2000 02:23:52 +0000 Subject: [PATCH] Add frontend support for "any" substrings assertions. Needs to be tied into index mask and backend search code. --- servers/slapd/schema_init.c | 232 +++++++++++++++++++++++++++++++----- servers/slapd/slap.h | 1 + tests/data/slapd.conf | 3 +- 3 files changed, 206 insertions(+), 30 deletions(-) diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 152d8d4421..bdf64138ba 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -868,6 +868,7 @@ int caseExactIA5Filter( *keysp = keys; return LDAP_SUCCESS; } + /* Substrings Index generation function */ int caseExactIA5SubstringsIndexer( unsigned flags, @@ -877,7 +878,7 @@ int caseExactIA5SubstringsIndexer( struct berval **values, struct berval ***keysp ) { - int i, nkeys, types; + ber_len_t i, nkeys; size_t slen, mlen; struct berval **keys; lutil_MD5_CTX MD5context; @@ -886,11 +887,6 @@ int caseExactIA5SubstringsIndexer( digest.bv_val = MD5digest; digest.bv_len = sizeof(MD5digest); - types = 0; - if( flags & SLAP_MR_SUBSTR_INITIAL ) types++; - if( flags & SLAP_MR_SUBSTR_FINAL ) types++; - /* no SUBSTR_ANY indexing */ - nkeys=0; for( i=0; values[i] != NULL; i++ ) { /* count number of indices to generate */ @@ -898,10 +894,28 @@ int caseExactIA5SubstringsIndexer( continue; } - if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { - nkeys += SLAP_INDEX_SUBSTR_MAXLEN - ( SLAP_INDEX_SUBSTR_MINLEN - 1); - } else { - nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); + if( flags & SLAP_MR_SUBSTR_INITIAL ) { + if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + nkeys += SLAP_INDEX_SUBSTR_MAXLEN - + ( SLAP_INDEX_SUBSTR_MINLEN - 1); + } else { + nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); + } + } + + if( flags & SLAP_MR_SUBSTR_ANY ) { + if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 ); + } + } + + if( flags & SLAP_MR_SUBSTR_FINAL ) { + if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + nkeys += SLAP_INDEX_SUBSTR_MAXLEN - + ( SLAP_INDEX_SUBSTR_MINLEN - 1); + } else { + nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); + } } } assert( i > 0 ); @@ -912,7 +926,6 @@ int caseExactIA5SubstringsIndexer( return LDAP_SUCCESS; } - nkeys *= types; /* We need to generate keys for each type */ keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) ); slen = strlen( syntax->ssyn_oid ); @@ -920,13 +933,40 @@ int caseExactIA5SubstringsIndexer( nkeys=0; for( i=0; values[i] != NULL; i++ ) { - int j,max; + ber_len_t j,max; struct berval *value; value = values[i]; - if( value->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue; + if( ( flags & SLAP_MR_SUBSTR_ANY ) && + ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) ) + { + char pre = SLAP_INDEX_SUBSTR_PREFIX; + max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1); + + for( j=0; jbv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + + lutil_MD5Update( &MD5context, + &pre, sizeof( pre ) ); + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + &value->bv_val[j], + SLAP_INDEX_SUBSTR_MAXLEN ); + lutil_MD5Final( MD5digest, &MD5context ); + + keys[nkeys++] = ber_bvdup( &digest ); + } + } + max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len; @@ -991,7 +1031,7 @@ int caseExactIA5SubstringsFilter( { SubstringsAssertion *sa = assertValue; char pre; - int nkeys = 0; + ber_len_t nkeys = 0; size_t slen, mlen, klen; struct berval **keys; lutil_MD5_CTX MD5context; @@ -1004,6 +1044,18 @@ int caseExactIA5SubstringsFilter( { nkeys++; } + + if( sa->sa_any ) { + ber_len_t i; + for( i=0; sa->sa_any[i] != NULL; i++ ) { + if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + /* don't bother accounting for stepping */ + nkeys += sa->sa_any[i]->bv_len - + ( SLAP_INDEX_SUBSTR_MAXLEN - 1 ); + } + } + } + if( sa->sa_final != NULL && sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { @@ -1051,6 +1103,40 @@ int caseExactIA5SubstringsFilter( keys[nkeys++] = ber_bvdup( &digest ); } + if( sa->sa_any ) { + ber_len_t i, j; + pre = SLAP_INDEX_SUBSTR_PREFIX; + klen = SLAP_INDEX_SUBSTR_MAXLEN; + + for( i=0; sa->sa_any[i] != NULL; i++ ) { + if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) { + continue; + } + + value = sa->sa_any[i]; + + for(j=0; jsa_any[i]->bv_len; j+= SLAP_INDEX_SUBSTR_STEP ) { + + lutil_MD5Init( &MD5context ); + if( prefix != NULL && prefix->bv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + lutil_MD5Update( &MD5context, + &pre, sizeof( pre ) ); + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + &value->bv_val[j], klen ); + lutil_MD5Final( MD5digest, &MD5context ); + + keys[nkeys++] = ber_bvdup( &digest ); + } + } + } + if( sa->sa_final != NULL && sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { @@ -1358,7 +1444,7 @@ int caseIgnoreIA5SubstringsIndexer( struct berval **values, struct berval ***keysp ) { - int i, nkeys, types; + ber_len_t i, nkeys; size_t slen, mlen; struct berval **keys; lutil_MD5_CTX MD5context; @@ -1367,11 +1453,6 @@ int caseIgnoreIA5SubstringsIndexer( digest.bv_val = MD5digest; digest.bv_len = sizeof(MD5digest); - types = 0; - if( flags & SLAP_MR_SUBSTR_INITIAL ) types++; - if( flags & SLAP_MR_SUBSTR_FINAL ) types++; - /* no SUBSTR_ANY indexing */ - nkeys=0; for( i=0; values[i] != NULL; i++ ) { /* count number of indices to generate */ @@ -1379,10 +1460,28 @@ int caseIgnoreIA5SubstringsIndexer( continue; } - if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { - nkeys += SLAP_INDEX_SUBSTR_MAXLEN - ( SLAP_INDEX_SUBSTR_MINLEN - 1); - } else { - nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); + if( flags & SLAP_MR_SUBSTR_INITIAL ) { + if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + nkeys += SLAP_INDEX_SUBSTR_MAXLEN - + ( SLAP_INDEX_SUBSTR_MINLEN - 1); + } else { + nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); + } + } + + if( flags & SLAP_MR_SUBSTR_ANY ) { + if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1 ); + } + } + + if( flags & SLAP_MR_SUBSTR_FINAL ) { + if( values[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + nkeys += SLAP_INDEX_SUBSTR_MAXLEN - + ( SLAP_INDEX_SUBSTR_MINLEN - 1); + } else { + nkeys += values[i]->bv_len - ( SLAP_INDEX_SUBSTR_MINLEN - 1 ); + } } } assert( i > 0 ); @@ -1393,7 +1492,6 @@ int caseIgnoreIA5SubstringsIndexer( return LDAP_SUCCESS; } - nkeys *= types; /* We need to generate keys for each type */ keys = ch_malloc( sizeof( struct berval * ) * (nkeys+1) ); slen = strlen( syntax->ssyn_oid ); @@ -1406,12 +1504,40 @@ int caseIgnoreIA5SubstringsIndexer( if( values[i]->bv_len < SLAP_INDEX_SUBSTR_MINLEN ) continue; - max = SLAP_INDEX_SUBSTR_MAXLEN < values[i]->bv_len - ? SLAP_INDEX_SUBSTR_MAXLEN : values[i]->bv_len; - value = ber_bvdup( values[i] ); ldap_pvt_str2upper( value->bv_val ); + if( ( flags & SLAP_MR_SUBSTR_ANY ) && + ( value->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) ) + { + char pre = SLAP_INDEX_SUBSTR_PREFIX; + max = value->bv_len - ( SLAP_INDEX_SUBSTR_MAXLEN - 1); + + for( j=0; jbv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + + lutil_MD5Update( &MD5context, + &pre, sizeof( pre ) ); + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + &value->bv_val[j], + SLAP_INDEX_SUBSTR_MAXLEN ); + lutil_MD5Final( MD5digest, &MD5context ); + + keys[nkeys++] = ber_bvdup( &digest ); + } + } + + max = SLAP_INDEX_SUBSTR_MAXLEN < value->bv_len + ? SLAP_INDEX_SUBSTR_MAXLEN : value->bv_len; + for( j=SLAP_INDEX_SUBSTR_MINLEN; j<=max; j++ ) { char pre; @@ -1475,7 +1601,7 @@ int caseIgnoreIA5SubstringsFilter( { SubstringsAssertion *sa = assertValue; char pre; - int nkeys = 0; + ber_len_t nkeys = 0; size_t slen, mlen, klen; struct berval **keys; lutil_MD5_CTX MD5context; @@ -1488,6 +1614,18 @@ int caseIgnoreIA5SubstringsFilter( { nkeys++; } + + if( sa->sa_any ) { + ber_len_t i; + for( i=0; sa->sa_any[i] != NULL; i++ ) { + if( sa->sa_any[i]->bv_len >= SLAP_INDEX_SUBSTR_MAXLEN ) { + /* don't bother accounting for stepping */ + nkeys += sa->sa_any[i]->bv_len - + ( SLAP_INDEX_SUBSTR_MAXLEN - 1 ); + } + } + } + if( sa->sa_final != NULL && sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { @@ -1537,6 +1675,42 @@ int caseIgnoreIA5SubstringsFilter( keys[nkeys++] = ber_bvdup( &digest ); } + if( sa->sa_any ) { + ber_len_t i, j; + pre = SLAP_INDEX_SUBSTR_PREFIX; + klen = SLAP_INDEX_SUBSTR_MAXLEN; + + for( i=0; sa->sa_any[i] != NULL; i++ ) { + if( sa->sa_any[i]->bv_len < SLAP_INDEX_SUBSTR_MAXLEN ) { + continue; + } + + value = ber_bvdup( sa->sa_any[i] ); + ldap_pvt_str2upper( value->bv_val ); + + for(j=0; jsa_any[i]->bv_len; j+= SLAP_INDEX_SUBSTR_STEP ) { + lutil_MD5Init( &MD5context ); + if( prefix != NULL && prefix->bv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + lutil_MD5Update( &MD5context, + &pre, sizeof( pre ) ); + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + &value->bv_val[j], klen ); + lutil_MD5Final( MD5digest, &MD5context ); + + keys[nkeys++] = ber_bvdup( &digest ); + } + + ber_bvfree( value ); + } + } + if( sa->sa_final != NULL && sa->sa_final->bv_len >= SLAP_INDEX_SUBSTR_MINLEN ) { diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 48e1b5d99b..28d289fe40 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -139,6 +139,7 @@ LDAP_SLAPD_F (int) slap_debug; #define SLAP_INDEX_SUBSTR_MINLEN 2 #define SLAP_INDEX_SUBSTR_MAXLEN 4 +#define SLAP_INDEX_SUBSTR_STEP 2 #define SLAP_INDEX_FLAGS 0xF000UL #define SLAP_INDEX_SUBTYPES 0x1000UL /* use index with subtypes */ diff --git a/tests/data/slapd.conf b/tests/data/slapd.conf index 0cac379f7f..413b16ec67 100644 --- a/tests/data/slapd.conf +++ b/tests/data/slapd.conf @@ -23,6 +23,7 @@ directory ./test-db rootdn "cn=Manager, o=University of Michigan, c=US" rootpw secret index objectclass eq -index cn,sn,uid pres,eq,sub +index uid pres,eq,sub +index cn,sn pres,eq,sub,subany dbnosync dbnolocking -- 2.39.5