Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/syntaxes
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv2672/ldap/servers/plugins/syntaxes
Modified Files:
string.c
Log Message:
Resolves: #447353
Summary: RFE: search optimization and single character substring searches
Description: extended the substring key to have 3 types:
* begin (e.g., *^a)
* middle (e.g., *abc)
* end (e.g., *xy$)
* Usage: turn an index object to extensibleobject and set an integer value as
follows:
* dn: cn=sn, cn=index, cn=userRoot, cn=ldbm database, cn=plugins, cn=config
* objectClass: extensibleObject
* nsSubStrBegin: 2
* nsSubStrMiddle: 3
* nsSubStrEnd: 2
* [...]
Index: string.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/syntaxes/string.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- string.c 30 Jun 2008 17:28:16 -0000 1.11
+++ string.c 15 Jul 2008 16:49:41 -0000 1.12
@@ -50,10 +50,12 @@
#include <unistd.h>
#endif
+#define MAX_VAL(x,y) ((x)>(y)?(x):(y))
+
static int string_filter_approx( struct berval *bvfilter,
Slapi_Value **bvals, Slapi_Value **retVal );
static void substring_comp_keys( Slapi_Value ***ivals, int *nsubs, char *str,
- int prepost, int syntax );
+ int prepost, int syntax, char *comp_buf, int substrlen );
int
string_filter_ava( struct berval *bvfilter, Slapi_Value **bvals, int syntax,
@@ -294,7 +296,7 @@
for ( j = 0; bvals[j] != NULL; j++ ) {
int tmprc;
size_t len;
- const struct berval *bvp = slapi_value_get_berval(bvals[j]);
+ const struct berval *bvp = slapi_value_get_berval(bvals[j]);
len = bvp->bv_len;
if ( len < sizeof(buf) ) {
@@ -392,8 +394,53 @@
/* XXX should remove duplicates! XXX */
Slapi_Value *bvdup;
const struct berval *bvp;
- char buf[SUBLEN+1];
+ char *buf;
int i;
+ int *substrlens = NULL;
+ int localsublens[3] = {SUBBEGIN, SUBMIDDLE, SUBEND};/* default values */
+ int maxsublen;
+ /*
+ * Substring key has 3 types:
+ * begin (e.g., *^a)
+ * middle (e.g., *abc)
+ * end (e.g., *xy$)
+ *
+ * the each has its own key length, which can be configured as follows:
+ * Usage: turn an index object to extensibleobject and
+ * set an integer value for each.
+ * dn: cn=sn, cn=index, cn=userRoot, cn=ldbm database, cn=plugins,
+ * cn=config
+ * objectClass: extensibleObject
+ * nsSubStrBegin: 2
+ * nsSubStrMiddle: 3
+ * nsSubStrEnd: 2
+ * [...]
+ *
+ * By default, begin == 2, middle == 3, end == 2 (defined in syntax.h)
+ */
+
+ /* If nsSubStrLen is specified in each index entry,
+ respect the length for the substring index key length.
+ Otherwise, the deafult value SUBLEN is used */
+ slapi_pblock_get(pb, SLAPI_SYNTAX_SUBSTRLENS, &substrlens);
+
+ if (NULL == substrlens) {
+ substrlens = localsublens;
+ }
+ if (0 == substrlens[INDEX_SUBSTRBEGIN]) {
+ substrlens[INDEX_SUBSTRBEGIN] = SUBBEGIN;
+ }
+ if (0 == substrlens[INDEX_SUBSTRMIDDLE]) {
+ substrlens[INDEX_SUBSTRMIDDLE] = SUBMIDDLE;
+ }
+ if (0 == substrlens[INDEX_SUBSTREND]) {
+ substrlens[INDEX_SUBSTREND] = SUBEND;
+ }
+ maxsublen = MAX_VAL(substrlens[INDEX_SUBSTRBEGIN], substrlens[INDEX_SUBSTRMIDDLE]);
+ maxsublen = MAX_VAL(maxsublen, substrlens[INDEX_SUBSTREND]);
+
+ buf = (char *)slapi_ch_calloc(1, maxsublen + 1);
+
nsubs = 0;
for ( bvlp = bvals; bvlp && *bvlp; bvlp++ ) {
/*
@@ -407,11 +454,11 @@
* the only downside is that we allocate more space than
* we really need.
*/
- nsubs += slapi_value_get_length(*bvlp) - SUBLEN + 3;
+ nsubs += slapi_value_get_length(*bvlp) - substrlens[INDEX_SUBSTRMIDDLE] + 3;
}
+ nsubs += substrlens[INDEX_SUBSTRMIDDLE] * 2 - substrlens[INDEX_SUBSTRBEGIN] -
substrlens[INDEX_SUBSTREND];
*ivals = (Slapi_Value **) slapi_ch_calloc( (nsubs + 1), sizeof(Slapi_Value *) );
- buf[SUBLEN] = '\0';
n = 0;
bvdup= slapi_value_new();
@@ -423,39 +470,42 @@
bvp = slapi_value_get_berval(bvdup);
/* leading */
- if ( bvp->bv_len > SUBLEN - 2 ) {
+ if ( bvp->bv_len > substrlens[INDEX_SUBSTRBEGIN] - 2 ) {
buf[0] = '^';
- for ( i = 0; i < SUBLEN - 1; i++ ) {
+ for ( i = 0; i < substrlens[INDEX_SUBSTRBEGIN] - 1; i++ ) {
buf[i + 1] = bvp->bv_val[i];
}
+ buf[substrlens[INDEX_SUBSTRBEGIN]] = '\0';
(*ivals)[n] = slapi_value_new_string(buf);
n++;
}
/* any */
for ( p = bvp->bv_val;
- p < (bvp->bv_val + bvp->bv_len - SUBLEN + 1);
+ p < (bvp->bv_val + bvp->bv_len - substrlens[INDEX_SUBSTRMIDDLE] + 1);
p++ ) {
- for ( i = 0; i < SUBLEN; i++ ) {
+ for ( i = 0; i < substrlens[INDEX_SUBSTRMIDDLE]; i++ ) {
buf[i] = p[i];
}
- buf[SUBLEN] = '\0';
+ buf[substrlens[INDEX_SUBSTRMIDDLE]] = '\0';
(*ivals)[n] = slapi_value_new_string(buf);
n++;
}
/* trailing */
- if ( bvp->bv_len > SUBLEN - 2 ) {
- p = bvp->bv_val + bvp->bv_len - SUBLEN + 1;
- for ( i = 0; i < SUBLEN - 1; i++ ) {
+ if ( bvp->bv_len > substrlens[INDEX_SUBSTREND] - 2 ) {
+ p = bvp->bv_val + bvp->bv_len - substrlens[INDEX_SUBSTREND] + 1;
+ for ( i = 0; i < substrlens[INDEX_SUBSTREND] - 1; i++ ) {
buf[i] = p[i];
}
- buf[SUBLEN - 1] = '$';
+ buf[substrlens[INDEX_SUBSTREND] - 1] = '$';
+ buf[substrlens[INDEX_SUBSTREND]] = '\0';
(*ivals)[n] = slapi_value_new_string(buf);
n++;
}
}
slapi_value_free(&bvdup);
+ slapi_ch_free_string(&buf);
}
break;
}
@@ -548,6 +598,25 @@
)
{
int nsubs, i, len;
+ int *substrlens = NULL;
+ int localsublens[3] = {SUBBEGIN, SUBMIDDLE, SUBEND};/* default values */
+ int maxsublen;
+ char *comp_buf = NULL;
+
+ slapi_pblock_get(pb, SLAPI_SYNTAX_SUBSTRLENS, &substrlens);
+
+ if (NULL == substrlens) {
+ substrlens = localsublens;
+ }
+ if (0 == substrlens[INDEX_SUBSTRBEGIN]) {
+ substrlens[INDEX_SUBSTRBEGIN] = SUBBEGIN;
+ }
+ if (0 == substrlens[INDEX_SUBSTRMIDDLE]) {
+ substrlens[INDEX_SUBSTRMIDDLE] = SUBMIDDLE;
+ }
+ if (0 == substrlens[INDEX_SUBSTREND]) {
+ substrlens[INDEX_SUBSTREND] = SUBEND;
+ }
*ivals = NULL;
@@ -561,8 +630,8 @@
nsubs = 0;
if ( initial != NULL ) {
value_normalize( initial, syntax, 0 /* do not trim leading blanks */ );
- if ( strlen( initial ) > SUBLEN - 2 ) {
- nsubs += strlen( initial ) - SUBLEN + 2;
+ if ( strlen( initial ) > substrlens[INDEX_SUBSTRBEGIN] - 2 ) {
+ nsubs += strlen( initial ) - substrlens[INDEX_SUBSTRBEGIN] + 2;
} else {
initial = NULL; /* save some work later */
}
@@ -570,14 +639,14 @@
for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
value_normalize( any[i], syntax, 0 /* do not trim leading blanks */ );
len = strlen( any[i] );
- if ( len >= SUBLEN ) {
- nsubs += len - SUBLEN + 1;
+ if ( len >= substrlens[INDEX_SUBSTRMIDDLE] ) {
+ nsubs += len - substrlens[INDEX_SUBSTRMIDDLE] + 1;
}
}
if ( final != NULL ) {
value_normalize( final, syntax, 0 /* do not trim leading blanks */ );
- if ( strlen( final ) > SUBLEN - 2 ) {
- nsubs += strlen( final ) - SUBLEN + 2;
+ if ( strlen( final ) > substrlens[INDEX_SUBSTREND] - 2 ) {
+ nsubs += strlen( final ) - substrlens[INDEX_SUBSTREND] + 2;
} else {
final = NULL; /* save some work later */
}
@@ -592,21 +661,29 @@
*/
*ivals = (Slapi_Value **) slapi_ch_malloc( (nsubs + 1) * sizeof(Slapi_Value *) );
+
+ maxsublen = MAX_VAL(substrlens[INDEX_SUBSTRBEGIN], substrlens[INDEX_SUBSTRMIDDLE]);
+ maxsublen = MAX_VAL(maxsublen, substrlens[INDEX_SUBSTREND]);
nsubs = 0;
+ comp_buf = (char *)slapi_ch_malloc(maxsublen + 1);
if ( initial != NULL ) {
- substring_comp_keys( ivals, &nsubs, initial, '^', syntax );
+ substring_comp_keys( ivals, &nsubs, initial, '^', syntax,
+ comp_buf, substrlens[INDEX_SUBSTRBEGIN] );
}
for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
- if ( strlen( any[i] ) < SUBLEN ) {
+ if ( strlen( any[i] ) < substrlens[INDEX_SUBSTRMIDDLE] ) {
continue;
}
- substring_comp_keys( ivals, &nsubs, any[i], 0, syntax );
+ substring_comp_keys( ivals, &nsubs, any[i], 0, syntax,
+ comp_buf, substrlens[INDEX_SUBSTRMIDDLE] );
}
if ( final != NULL ) {
- substring_comp_keys( ivals, &nsubs, final, '$', syntax );
+ substring_comp_keys( ivals, &nsubs, final, '$', syntax,
+ comp_buf, substrlens[INDEX_SUBSTREND] );
}
(*ivals)[nsubs] = NULL;
+ slapi_ch_free_string(&comp_buf);
return( 0 );
}
@@ -617,12 +694,15 @@
int *nsubs,
char *str,
int prepost,
- int syntax
+ int syntax,
+ char *comp_buf,
+ int substrlen
)
{
int i, len;
char *p;
- char buf[SUBLEN + 1];
+
+ PR_ASSERT(NULL != comp_buf);
LDAPDebug( LDAP_DEBUG_TRACE, "=> substring_comp_keys (%s) %d\n",
str, prepost, 0 );
@@ -632,37 +712,37 @@
/* prepend ^ for initial substring */
if ( prepost == '^' )
{
- buf[0] = '^';
- for ( i = 0; i < SUBLEN - 1; i++ )
+ comp_buf[0] = '^';
+ for ( i = 0; i < substrlen - 1; i++ )
{
- buf[i + 1] = str[i];
+ comp_buf[i + 1] = str[i];
}
- buf[SUBLEN] = '\0';
- (*ivals)[*nsubs] = slapi_value_new_string(buf);
+ comp_buf[substrlen] = '\0';
+ (*ivals)[*nsubs] = slapi_value_new_string(comp_buf);
(*nsubs)++;
}
- for ( p = str; p < (str + len - SUBLEN + 1); p++ )
+ for ( p = str; p < (str + len - substrlen + 1); p++ )
{
- for ( i = 0; i < SUBLEN; i++ )
+ for ( i = 0; i < substrlen; i++ )
{
- buf[i] = p[i];
+ comp_buf[i] = p[i];
}
- buf[SUBLEN] = '\0';
- (*ivals)[*nsubs] = slapi_value_new_string(buf);
+ comp_buf[substrlen] = '\0';
+ (*ivals)[*nsubs] = slapi_value_new_string(comp_buf);
(*nsubs)++;
}
if ( prepost == '$' )
{
- p = str + len - SUBLEN + 1;
- for ( i = 0; i < SUBLEN - 1; i++ )
+ p = str + len - substrlen + 1;
+ for ( i = 0; i < substrlen - 1; i++ )
{
- buf[i] = p[i];
+ comp_buf[i] = p[i];
}
- buf[SUBLEN - 1] = '$';
- buf[SUBLEN] = '\0';
- (*ivals)[*nsubs] = slapi_value_new_string(buf);
+ comp_buf[substrlen - 1] = '$';
+ comp_buf[substrlen] = '\0';
+ (*ivals)[*nsubs] = slapi_value_new_string(comp_buf);
(*nsubs)++;
}