From 3ff3957dc7d376775919335f86bf2829230b27e0 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 21 Nov 2007 02:54:57 +0000 Subject: [PATCH] Add index_intlen keyword for ordered indexing of integers --- servers/slapd/bconfig.c | 26 ++++++- servers/slapd/proto-slap.h | 1 + servers/slapd/schema_init.c | 148 +++++++++++++++++++++++++++++++++++- 3 files changed, 171 insertions(+), 4 deletions(-) diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 7aa86fbbad..b4a5b58494 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -179,6 +179,7 @@ enum { CFG_MONITORING, CFG_SERVERID, CFG_SORTVALS, + CFG_IX_INTLEN, CFG_LAST }; @@ -372,6 +373,9 @@ static ConfigTable config_back_cf_table[] = { { "index_substr_any_step", "step", 2, 2, 0, ARG_INT|ARG_NONZERO, &index_substr_any_step, "( OLcfgGlAt:23 NAME 'olcIndexSubstrAnyStep' " "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, + { "index_intlen", "len", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_IX_INTLEN, + &config_generic, "( OLcfgGlAt:84 NAME 'olcIndexIntLen' " + "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, { "lastmod", "on|off", 2, 2, 0, ARG_DB|ARG_ON_OFF|ARG_MAGIC|CFG_LASTMOD, &config_generic, "( OLcfgDbAt:0.4 NAME 'olcLastMod' " "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL }, @@ -709,8 +713,8 @@ static ConfigOCs cf_ocs[] = { "olcConnMaxPending $ olcConnMaxPendingAuth $ " "olcDisallows $ olcGentleHUP $ olcIdleTimeout $ " "olcIndexSubstrIfMaxLen $ olcIndexSubstrIfMinLen $ " - "olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcLocalSSF $ " - "olcLogLevel $ " + "olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcIndexIntLen $ " + "olcLocalSSF $ olcLogLevel $ " "olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPidFile $ " "olcPluginLogFile $ olcReadOnly $ olcReferral $ " "olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ " @@ -1014,6 +1018,12 @@ config_generic(ConfigArgs *c) { case CFG_SSTR_IF_MIN: c->value_int = index_substr_if_minlen; break; + case CFG_IX_INTLEN: + if ( index_intlen ) + c->value_int = index_intlen; + else + rc = 1; + break; case CFG_SORTVALS: { ADlist *sv; rc = 1; @@ -1151,6 +1161,11 @@ config_generic(ConfigArgs *c) { c->be->be_flags &= ~SLAP_DBFLAG_HIDDEN; break; + case CFG_IX_INTLEN: + index_intlen = 0; + slap_schema.si_mr_integerMatch->smr_usage &= ~SLAP_MR_ORDERED_INDEX; + break; + case CFG_ACL: if ( c->valx < 0 ) { AccessControl *end; @@ -1494,6 +1509,13 @@ config_generic(ConfigArgs *c) { return(1); break; + case CFG_IX_INTLEN: + if ( c->value_int < 4 ) + c->value_int = 4; + index_intlen = c->value_int; + slap_schema.si_mr_integerMatch->smr_usage |= SLAP_MR_ORDERED_INDEX; + break; + case CFG_SORTVALS: { ADlist *svnew = NULL, *svtail, *sv; diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index d53fd93cb0..a800fd1568 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -1863,6 +1863,7 @@ LDAP_SLAPD_V (unsigned int) index_substr_if_minlen; LDAP_SLAPD_V (unsigned int) index_substr_if_maxlen; LDAP_SLAPD_V (unsigned int) index_substr_any_len; LDAP_SLAPD_V (unsigned int) index_substr_any_step; +LDAP_SLAPD_V (unsigned int) index_intlen; LDAP_SLAPD_V (ber_len_t) sockbuf_max_incoming; LDAP_SLAPD_V (ber_len_t) sockbuf_max_incoming_auth; diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index f318a75564..960c55623c 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -62,6 +62,9 @@ unsigned int index_substr_if_maxlen = SLAP_INDEX_SUBSTR_IF_MAXLEN_DEFAULT; unsigned int index_substr_any_len = SLAP_INDEX_SUBSTR_ANY_LEN_DEFAULT; unsigned int index_substr_any_step = SLAP_INDEX_SUBSTR_ANY_STEP_DEFAULT; +/* Default to no ordered integer indexing */ +unsigned int index_intlen = 0; + ldap_pvt_thread_mutex_t ad_undef_mutex; ldap_pvt_thread_mutex_t oc_undef_mutex; @@ -2109,7 +2112,148 @@ integerMatch( *matchp = match; return LDAP_SUCCESS; } - + +/* Index generation function */ +static int +integerIndexer( + slap_mask_t use, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *prefix, + BerVarray values, + BerVarray *keysp, + void *ctx ) +{ + char ibuf[64]; + struct berval iv, itmp; + BerVarray keys; + int i, rc; + + if ( !index_intlen ) { + return octetStringIndexer( use, flags, syntax, mr, + prefix, values, keysp, ctx ); + } + + for( i=0; !BER_BVISNULL( &values[i] ); i++ ) { + /* just count them */ + } + + /* we should have at least one value at this point */ + assert( i > 0 ); + + keys = slap_sl_malloc( sizeof( struct berval ) * (i+1), ctx ); + for ( i = 0; !BER_BVISNULL( &values[i] ); i++ ) { + keys[i].bv_len = index_intlen+1; + keys[i].bv_val = slap_sl_malloc( index_intlen+1, ctx ); + } + keys[i].bv_len = 0; + keys[i].bv_val = NULL; + + itmp.bv_val = ibuf; + itmp.bv_len = sizeof(ibuf); + + for ( i=0; !BER_BVISNULL( &values[i] ); i++ ) { + if ( values[i].bv_len > itmp.bv_len ) { + itmp.bv_len = values[i].bv_len; + if ( itmp.bv_val == ibuf ) { + itmp.bv_val = slap_sl_malloc( itmp.bv_len, ctx ); + } else { + itmp.bv_val = slap_sl_realloc( itmp.bv_val, itmp.bv_len, ctx ); + } + } + iv = itmp; + if ( lutil_str2bin( &values[i], &iv )) { + rc = LDAP_INVALID_SYNTAX; + goto leave; + } + /* If too small, pad with zeros */ + if ( iv.bv_len < index_intlen ) { + int j, k; + keys[i].bv_val[0] = index_intlen; + k = index_intlen - iv.bv_len + 1; + for ( j=1; jbv_len > sizeof( ibuf )) { + iv.bv_val = slap_sl_malloc( value->bv_len, ctx ); + iv.bv_len = value->bv_len; + } else { + iv.bv_val = ibuf; + iv.bv_len = sizeof(ibuf); + } + + if ( lutil_str2bin( value, &iv )) { + rc = LDAP_INVALID_SYNTAX; + goto leave; + } + /* If too small, pad with zeros */ + if ( iv.bv_len < index_intlen ) { + int j, k; + keys[0].bv_val[0] = index_intlen; + k = index_intlen - iv.bv_len + 1; + for ( j=1; j