X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-bdb%2Fattr.c;h=15a28a91ba2bf6b9363365a168195811061c4a00;hb=0af1940f3fb59fe57b2281ef253fe1341c505c2c;hp=73c35c86c2078cce61b68f50d253d1dd1aac6828;hpb=dc0eacd40b625258355eea866d62188e5aa7ce3b;p=openldap diff --git a/servers/slapd/back-bdb/attr.c b/servers/slapd/back-bdb/attr.c index 73c35c86c2..15a28a91ba 100644 --- a/servers/slapd/back-bdb/attr.c +++ b/servers/slapd/back-bdb/attr.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2000-2005 The OpenLDAP Foundation. + * Copyright 2000-2006 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,63 +23,67 @@ #include "slap.h" #include "back-bdb.h" +#include "lutil.h" -/* for the cache of attribute information (which are indexed, etc.) */ -typedef struct bdb_attrinfo { - AttributeDescription *ai_desc; /* attribute description cn;lang-en */ - slap_mask_t ai_indexmask; /* how the attr is indexed */ -#ifdef LDAP_COMP_MATCH - ComponentReference* ai_cr; /*component indexing*/ -#endif -} AttrInfo; - -static int -ainfo_type_cmp( - const void *v_desc, - const void *v_a -) +/* Find the ad, return -1 if not found, + * set point for insertion if ins is non-NULL + */ +int +bdb_attr_slot( struct bdb_info *bdb, AttributeDescription *ad, unsigned *ins ) { - const AttributeDescription *desc = v_desc; - const AttrInfo *a = v_a; - return SLAP_PTRCMP(desc, a->ai_desc); + unsigned base = 0, cursor = 0; + unsigned n = bdb->bi_nattrs; + int val = 0; + + while ( 0 < n ) { + int pivot = n >> 1; + cursor = base + pivot; + + val = SLAP_PTRCMP( ad, bdb->bi_attrs[cursor]->ai_desc ); + if ( val < 0 ) { + n = pivot; + } else if ( val > 0 ) { + base = cursor + 1; + n -= pivot + 1; + } else { + return cursor; + } + } + if ( ins ) { + if ( val > 0 ) + ++cursor; + *ins = cursor; + } + return -1; } static int -ainfo_cmp( - const void *v_a, - const void *v_b -) -{ - const AttrInfo *a = v_a, *b = v_b; - return SLAP_PTRCMP(a->ai_desc, b->ai_desc); -} - -#ifdef LDAP_COMP_MATCH -void -bdb_attr_comp_ref( - struct bdb_info *bdb, - AttributeDescription *desc, - ComponentReference** cr ) +ainfo_insert( struct bdb_info *bdb, AttrInfo *a ) { - AttrInfo *a; - - a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp ); - - *cr = a != NULL ? a->ai_cr : 0 ; + unsigned x; + int i = bdb_attr_slot( bdb, a->ai_desc, &x ); + + /* Is it a dup? */ + if ( i >= 0 ) + return -1; + + bdb->bi_attrs = ch_realloc( bdb->bi_attrs, ( bdb->bi_nattrs+1 ) * + sizeof( AttrInfo * )); + if ( x < bdb->bi_nattrs ) + AC_MEMCPY( &bdb->bi_attrs[x+1], &bdb->bi_attrs[x], + ( bdb->bi_nattrs - x ) * sizeof( AttrInfo *)); + bdb->bi_attrs[x] = a; + bdb->bi_nattrs++; + return 0; } -#endif -void +AttrInfo * bdb_attr_mask( struct bdb_info *bdb, - AttributeDescription *desc, - slap_mask_t *indexmask ) + AttributeDescription *desc ) { - AttrInfo *a; - - a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp ); - - *indexmask = a != NULL ? a->ai_indexmask : 0; + int i = bdb_attr_slot( bdb, desc, NULL ); + return i < 0 ? NULL : bdb->bi_attrs[i]; } int @@ -90,7 +94,7 @@ bdb_attr_index_config( int argc, char **argv ) { - int rc; + int rc = 0; int i; slap_mask_t mask; char **attrs; @@ -112,7 +116,8 @@ bdb_attr_index_config( fprintf( stderr, "%s: line %d: " "no indexes specified: %s\n", fname, lineno, argv[1] ); - return LDAP_PARAM_ERROR; + rc = LDAP_PARAM_ERROR; + goto done; } } @@ -130,7 +135,8 @@ bdb_attr_index_config( fprintf( stderr, "%s: line %d: " "index type \"%s\" undefined\n", fname, lineno, indexes[i] ); - return LDAP_PARAM_ERROR; + rc = LDAP_PARAM_ERROR; + goto done; } mask |= index; @@ -141,7 +147,8 @@ bdb_attr_index_config( fprintf( stderr, "%s: line %d: " "no indexes selected\n", fname, lineno ); - return LDAP_PARAM_ERROR; + rc = LDAP_PARAM_ERROR; + goto done; } for ( i = 0; attrs[i] != NULL; i++ ) { @@ -165,7 +172,7 @@ bdb_attr_index_config( fprintf( stderr, "%s: line %d: " "index component reference\"%s\" undefined\n", fname, lineno, attrs[i] ); - return rc; + goto done; } cr->cr_indexmask = mask; /* @@ -175,11 +182,6 @@ bdb_attr_index_config( } else { cr = NULL; } -#endif - a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) ); - -#ifdef LDAP_COMP_MATCH - a->ai_cr = NULL; #endif ad = NULL; rc = slap_str2ad( attrs[i], &ad, &text ); @@ -188,14 +190,15 @@ bdb_attr_index_config( fprintf( stderr, "%s: line %d: " "index attribute \"%s\" undefined\n", fname, lineno, attrs[i] ); - return rc; + goto done; } if( slap_ad_is_binary( ad ) ) { fprintf( stderr, "%s: line %d: " "index of attribute \"%s\" disallowed\n", fname, lineno, attrs[i] ); - return LDAP_UNWILLING_TO_PERFORM; + rc = LDAP_UNWILLING_TO_PERFORM; + goto done; } if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !( @@ -206,7 +209,8 @@ bdb_attr_index_config( fprintf( stderr, "%s: line %d: " "approx index of attribute \"%s\" disallowed\n", fname, lineno, attrs[i] ); - return LDAP_INAPPROPRIATE_MATCHING; + rc = LDAP_INAPPROPRIATE_MATCHING; + goto done; } if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !( @@ -217,7 +221,8 @@ bdb_attr_index_config( fprintf( stderr, "%s: line %d: " "equality index of attribute \"%s\" disallowed\n", fname, lineno, attrs[i] ); - return LDAP_INAPPROPRIATE_MATCHING; + rc = LDAP_INAPPROPRIATE_MATCHING; + goto done; } if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !( @@ -228,17 +233,31 @@ bdb_attr_index_config( fprintf( stderr, "%s: line %d: " "substr index of attribute \"%s\" disallowed\n", fname, lineno, attrs[i] ); - return LDAP_INAPPROPRIATE_MATCHING; + rc = LDAP_INAPPROPRIATE_MATCHING; + goto done; } Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04lx\n", ad->ad_cname.bv_val, mask, 0 ); + a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) ); + +#ifdef LDAP_COMP_MATCH + a->ai_cr = NULL; +#endif a->ai_desc = ad; - a->ai_indexmask = mask; + + if ( bdb->bi_flags & BDB_IS_OPEN ) { + a->ai_indexmask = 0; + a->ai_newmask = mask; + } else { + a->ai_indexmask = mask; + a->ai_newmask = 0; + } + #ifdef LDAP_COMP_MATCH if ( cr ) { - a_cr = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp ); + a_cr = bdb_attr_mask( bdb, ad ); if ( a_cr ) { /* * AttrInfo is already in AVL @@ -248,39 +267,131 @@ bdb_attr_index_config( rc = insert_component_reference( cr, &a_cr->ai_cr ); if ( rc != LDAP_SUCCESS) { fprintf( stderr, " error during inserting component reference in %s ", attrs[i]); - return LDAP_PARAM_ERROR; + rc = LDAP_PARAM_ERROR; + goto done; } continue; } else { rc = insert_component_reference( cr, &a->ai_cr ); if ( rc != LDAP_SUCCESS) { fprintf( stderr, " error during inserting component reference in %s ", attrs[i]); - return LDAP_PARAM_ERROR; + rc = LDAP_PARAM_ERROR; + goto done; } } } #endif - rc = avl_insert( &bdb->bi_attrs, (caddr_t) a, - ainfo_cmp, avl_dup_error ); - + rc = ainfo_insert( bdb, a ); if( rc ) { - fprintf( stderr, "%s: line %d: duplicate index definition " - "for attr \"%s\" (ignored)\n", + if ( bdb->bi_flags & BDB_IS_OPEN ) { + AttrInfo *b = bdb_attr_mask( bdb, ad ); + /* If we were editing this attr, reset it */ + b->ai_indexmask &= ~BDB_INDEX_DELETING; + /* If this is leftover from a previous add, commit it */ + if ( b->ai_newmask ) + b->ai_indexmask = b->ai_newmask; + b->ai_newmask = a->ai_newmask; + ch_free( a ); + continue; + } + fprintf( stderr, + "%s: line %d: duplicate index definition for attr \"%s\".\n", fname, lineno, attrs[i] ); - return LDAP_PARAM_ERROR; + rc = LDAP_PARAM_ERROR; + goto done; } } +done: ldap_charray_free( attrs ); if ( indexes != NULL ) ldap_charray_free( indexes ); - return LDAP_SUCCESS; + return rc; +} + +static int +bdb_attr_index_unparser( void *v1, void *v2 ) +{ + AttrInfo *ai = v1; + BerVarray *bva = v2; + struct berval bv; + char *ptr; + + slap_index2bvlen( ai->ai_indexmask, &bv ); + if ( bv.bv_len ) { + bv.bv_len += ai->ai_desc->ad_cname.bv_len + 1; + ptr = ch_malloc( bv.bv_len+1 ); + bv.bv_val = lutil_strcopy( ptr, ai->ai_desc->ad_cname.bv_val ); + *bv.bv_val++ = ' '; + slap_index2bv( ai->ai_indexmask, &bv ); + bv.bv_val = ptr; + ber_bvarray_add( bva, &bv ); + } + return 0; +} + +static AttributeDescription addef = { NULL, NULL, BER_BVC("default") }; +static AttrInfo aidef = { &addef }; + +void +bdb_attr_index_unparse( struct bdb_info *bdb, BerVarray *bva ) +{ + int i; + + if ( bdb->bi_defaultmask ) { + aidef.ai_indexmask = bdb->bi_defaultmask; + bdb_attr_index_unparser( &aidef, bva ); + } + for ( i=0; ibi_nattrs; i++ ) + bdb_attr_index_unparser( bdb->bi_attrs[i], bva ); } void -bdb_attr_index_destroy( Avlnode *tree ) +bdb_attr_info_free( AttrInfo *ai ) { - avl_free( tree, free ); +#ifdef LDAP_COMP_MATCH + free( ai->ai_cr ); +#endif + free( ai ); +} + +void +bdb_attr_index_destroy( struct bdb_info *bdb ) +{ + int i; + + for ( i=0; ibi_nattrs; i++ ) + bdb_attr_info_free( bdb->bi_attrs[i] ); + + free( bdb->bi_attrs ); } +void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad ) +{ + int i; + + i = bdb_attr_slot( bdb, ad, NULL ); + if ( i >= 0 ) { + bdb_attr_info_free( bdb->bi_attrs[i] ); + bdb->bi_nattrs--; + for (; ibi_nattrs; i++) + bdb->bi_attrs[i] = bdb->bi_attrs[i+1]; + } +} + +void bdb_attr_flush( struct bdb_info *bdb ) +{ + int i; + + for ( i=0; ibi_nattrs; i++ ) { + if ( bdb->bi_attrs[i]->ai_indexmask & BDB_INDEX_DELETING ) { + int j; + bdb_attr_info_free( bdb->bi_attrs[i] ); + bdb->bi_nattrs--; + for (j=i; jbi_nattrs; j++) + bdb->bi_attrs[j] = bdb->bi_attrs[j+1]; + i--; + } + } +}