]> git.sur5r.net Git - openldap/commitdiff
Add index_intlen keyword for ordered indexing of integers
authorHoward Chu <hyc@openldap.org>
Wed, 21 Nov 2007 02:54:57 +0000 (02:54 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 21 Nov 2007 02:54:57 +0000 (02:54 +0000)
servers/slapd/bconfig.c
servers/slapd/proto-slap.h
servers/slapd/schema_init.c

index 7aa86fbbadf88c811139f49d0c3cd182861cef28..b4a5b5849486bbd6e1f10b3ffef204b3ae768015 100644 (file)
@@ -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;
 
index d53fd93cb00655661f7ca18634353383bdbf06e3..a800fd1568e02878f18338cd0a58f6a5abdbe212 100644 (file)
@@ -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;
index f318a7556476370276add4d1c6eb4b38c4c3ddd9..960c55623c8875f0640e09eaf306ebdd8a6e28ea 100644 (file)
@@ -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; j<k; j++)
+                               keys[i].bv_val[j] = 0;
+                       for ( j = 0; j<iv.bv_len; j++ )
+                               keys[i].bv_val[j+k] = iv.bv_val[j];
+               } else {
+                       keys[i].bv_val[0] = iv.bv_len;
+                       memcpy( keys[i].bv_val+1, iv.bv_val, index_intlen );
+               }
+       }
+       *keysp = keys;
+       rc = 0;
+leave:
+       if ( itmp.bv_val != ibuf ) {
+               slap_sl_free( itmp.bv_val, ctx );
+       }
+       return rc;
+}
+
+/* Index generation function */
+static int
+integerFilter(
+       slap_mask_t use,
+       slap_mask_t flags,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *prefix,
+       void * assertedValue,
+       BerVarray *keysp,
+       void *ctx )
+{
+       char ibuf[64];
+       struct berval iv;
+       BerVarray keys;
+       struct berval *value;
+       int i, rc;
+
+       if ( !index_intlen ) {
+               return octetStringFilter( use, flags, syntax, mr,
+                       prefix, assertedValue, keysp, ctx );
+       }
+
+       value = (struct berval *) assertedValue;
+
+       keys = slap_sl_malloc( sizeof( struct berval ) * 2, ctx );
+
+       keys[0].bv_len = index_intlen + 1;
+       keys[0].bv_val = slap_sl_malloc( index_intlen+1, ctx );
+
+       if ( value->bv_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<k; j++)
+                       keys[0].bv_val[j] = 0;
+               for ( j = 0; j<iv.bv_len; j++ )
+                       keys[0].bv_val[j+k] = iv.bv_val[j];
+       } else {
+               keys[0].bv_val[0] = iv.bv_len;
+               memcpy( keys[0].bv_val+1, iv.bv_val, index_intlen );
+       }
+       rc = 0;
+       *keysp = keys;
+leave:
+       if ( iv.bv_val != ibuf ) {
+               slap_sl_free( iv.bv_val, ctx );
+       }
+       return rc;
+}
+
 static int
 countryStringValidate(
        Syntax *syntax,
@@ -4652,7 +4796,7 @@ static slap_mrule_defs_rec mrule_defs[] = {
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
                SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
                NULL, NULL, integerMatch,
-               octetStringIndexer, octetStringFilter,
+               integerIndexer, integerFilter,
                NULL },
 
        {"( 2.5.13.15 NAME 'integerOrderingMatch' "