diff options
author | Nathan Kinder <nkinder@redhat.com> | 2005-08-12 05:49:55 +0000 |
---|---|---|
committer | Nathan Kinder <nkinder@redhat.com> | 2005-08-12 05:49:55 +0000 |
commit | 2aa495ed6362c1d38b513e35b3c3d2bb1cad89e0 (patch) | |
tree | be84d7111d704529e5a9141dabf3fae44271d903 /ldap | |
parent | d3c8a955c23aae8a39030012b81efcc51868a909 (diff) | |
download | ds-2aa495ed6362c1d38b513e35b3c3d2bb1cad89e0.tar.gz ds-2aa495ed6362c1d38b513e35b3c3d2bb1cad89e0.tar.xz ds-2aa495ed6362c1d38b513e35b3c3d2bb1cad89e0.zip |
164843 - Modified indexing to deal with attribute subtypes
Diffstat (limited to 'ldap')
-rw-r--r-- | ldap/servers/slapd/back-ldbm/back-ldbm.h | 1 | ||||
-rw-r--r-- | ldap/servers/slapd/back-ldbm/index.c | 205 | ||||
-rw-r--r-- | ldap/servers/slapd/libslapd.def | 1 | ||||
-rw-r--r-- | ldap/servers/slapd/slapi-private.h | 1 |
4 files changed, 171 insertions, 37 deletions
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h index 0a0e3553..f4699863 100644 --- a/ldap/servers/slapd/back-ldbm/back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h @@ -637,6 +637,7 @@ typedef struct _back_search_result_set #define BE_INDEX_PRESENCE 4 /* (w/DEL) remove the presence index */ #define BE_INDEX_TOMBSTONE 8 /* Index entry as a tombstone */ #define BE_INDEX_DONT_ENCRYPT 16 /* Disable any encryption if this flag is set */ +#define BE_INDEX_EQUALITY 32 /* (w/DEL) remove the equality index */ /* Name of attribute type used for binder-based look through limit */ #define LDBM_LOOKTHROUGHLIMIT_AT "nsLookThroughLimit" diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c index e9fac76d..6e31042d 100644 --- a/ldap/servers/slapd/back-ldbm/index.c +++ b/ldap/servers/slapd/back-ldbm/index.c @@ -453,35 +453,118 @@ index_add_mods( ) { int rc = 0; - int i; - Slapi_Attr *attr; + int i, j; ID id = olde->ep_id; - Slapi_Value **svals = NULL; + int flags = 0; + char buf[SLAPD_TYPICAL_ATTRIBUTE_NAME_MAX_LENGTH]; + char *basetype = NULL; + char *tmp = NULL; + Slapi_Attr *curr_attr = NULL; + Slapi_ValueSet *all_vals = NULL; + Slapi_ValueSet *mod_vals = NULL; + Slapi_Value **evals = NULL; /* values that still exist after a + * delete. + */ + Slapi_Value **mods_valueArray = NULL; /* values that are specified in this + * operation. + */ + Slapi_Value **deleted_valueArray = NULL; /* values whose index entries + * should be deleted. + */ for ( i = 0; mods[i] != NULL; i++ ) { + /* Get base attribute type */ + basetype = buf; + tmp = slapi_attr_basetype(mods[i]->mod_type, buf, sizeof(buf)); + if(tmp != NULL) { + basetype = tmp; /* basetype was malloc'd */ + } + + /* Get a list of all remaining values for the base type + * and any present subtypes. + */ + all_vals = slapi_valueset_new(); + + for (curr_attr = newe->ep_entry->e_attrs; curr_attr != NULL; curr_attr = curr_attr->a_next) { + if (slapi_attr_type_cmp( basetype, curr_attr->a_type, SLAPI_TYPE_CMP_BASE ) == 0) { + valueset_add_valuearray(all_vals, attr_get_present_values(curr_attr)); + } + } + + evals = valueset_get_valuearray(all_vals); + + /* Get a list of all values specified in the operation. + */ + if ( mods[i]->mod_bvalues != NULL ) { + valuearray_init_bervalarray(mods[i]->mod_bvalues, + &mods_valueArray); + } + switch ( mods[i]->mod_op & ~LDAP_MOD_BVALUES ) { case LDAP_MOD_REPLACE: + flags = BE_INDEX_DEL; + /* Get a list of all values being deleted. + */ + mod_vals = slapi_valueset_new(); + + for (curr_attr = olde->ep_entry->e_attrs; curr_attr != NULL; curr_attr = curr_attr->a_next) { + if (slapi_attr_type_cmp( mods[i]->mod_type, curr_attr->a_type, SLAPI_TYPE_CMP_EXACT ) == 0) { + valueset_add_valuearray(mod_vals, attr_get_present_values(curr_attr)); + } + } + + deleted_valueArray = valueset_get_valuearray(mod_vals); + + /* If subtypes exist, don't remove the presence + * index. + */ + if ( evals != NULL && deleted_valueArray != NULL) { + /* evals will contain the new value that is being + * added as part of the replace operation if one + * was specified. We must remove this value from + * evals to know if any subtypes are present. + */ + slapi_entry_attr_find( olde->ep_entry, mods[i]->mod_type, &curr_attr ); + if ( mods_valueArray != NULL ) { + for ( j = 0; mods_valueArray[j] != NULL; j++ ) { + valuearray_remove_value(curr_attr, evals, mods_valueArray[j]); + } + } + + /* Search evals for the values being deleted. If + * they don't exist, delete the equality index. + */ + for ( j = 0; deleted_valueArray[j] != NULL; j++ ) { + if (valuearray_find(curr_attr, evals, deleted_valueArray[j]) == -1) { + if (!(flags & BE_INDEX_EQUALITY)) { + flags |= BE_INDEX_EQUALITY; + } + } else { + /* Remove duplicate value from deleted value array */ + valuearray_remove_value(curr_attr, deleted_valueArray, deleted_valueArray[j]); + j--; + } + } + } else { + flags |= BE_INDEX_PRESENCE|BE_INDEX_EQUALITY; + } + /* We need to first remove the old values from the * index. */ - if ( slapi_entry_attr_find( olde->ep_entry, mods[i]->mod_type, &attr ) == 0 && - (svals = attr_get_present_values(attr)) != NULL ) { index_addordel_values_sv( be, mods[i]->mod_type, - svals, NULL, id, - BE_INDEX_DEL|BE_INDEX_PRESENCE, - txn ); - } + deleted_valueArray, evals, id, + flags, txn ); + + /* Free valuearray */ + slapi_valueset_free(mod_vals); case LDAP_MOD_ADD: - if ( mods[i]->mod_bvalues == NULL ) { + if ( mods_valueArray == NULL ) { rc = 0; } else { - Slapi_Value **mods_valueArray = NULL; - valuearray_init_bervalarray(mods[i]->mod_bvalues, - &mods_valueArray); rc = index_addordel_values_sv( be, mods[i]->mod_type, mods_valueArray, NULL, id, BE_INDEX_ADD, txn ); - valuearray_free(&mods_valueArray); } break; @@ -489,44 +572,88 @@ index_add_mods( if ( (mods[i]->mod_bvalues == NULL) || (mods[i]->mod_bvalues[0] == NULL) ) { rc = 0; - /* if no value are specified all the values will - * be suppressed -> remove the presence index + flags = BE_INDEX_DEL; + + /* Get a list of all values that are being + * deleted. + */ + mod_vals = slapi_valueset_new(); + + for (curr_attr = olde->ep_entry->e_attrs; curr_attr != NULL; curr_attr = curr_attr->a_next) { + if (slapi_attr_type_cmp( mods[i]->mod_type, curr_attr->a_type, SLAPI_TYPE_CMP_EXACT ) == 0) { + valueset_add_valuearray(mod_vals, attr_get_present_values(curr_attr)); + } + } + + deleted_valueArray = valueset_get_valuearray(mod_vals); + + /* If subtypes exist, don't remove the + * presence index. */ - if ( slapi_entry_attr_find( olde->ep_entry, mods[i]->mod_type, &attr ) == 0 && - (svals = attr_get_present_values(attr)) != NULL ) { - index_addordel_values_sv( be, mods[i]->mod_type, - svals, NULL, id, BE_INDEX_DEL|BE_INDEX_PRESENCE, txn); + if (evals != NULL) { + for (curr_attr = newe->ep_entry->e_attrs; (curr_attr != NULL); + curr_attr = curr_attr->a_next) { + if (slapi_attr_type_cmp( basetype, curr_attr->a_type, SLAPI_TYPE_CMP_BASE ) == 0) { + /* Check if the any values being deleted + * also exist in a subtype. + */ + for ( j=0; deleted_valueArray[j] != NULL; j++) { + if ( valuearray_find(curr_attr, evals, deleted_valueArray[j]) == -1 ) { + /* If the equality flag isn't already set, set it */ + if (!(flags & BE_INDEX_EQUALITY)) { + flags |= BE_INDEX_EQUALITY; + } + } else { + /* Remove duplicate value from the mod list */ + valuearray_remove_value(curr_attr, deleted_valueArray, deleted_valueArray[j]); + j--; + } + } + } + } + } else { + flags = BE_INDEX_DEL|BE_INDEX_PRESENCE|BE_INDEX_EQUALITY; } + + /* Update the index */ + index_addordel_values_sv( be, mods[i]->mod_type, + deleted_valueArray, evals, id, flags, txn); + + slapi_valueset_free(mod_vals); } else { + /* determine if the presence key should be * removed (are we removing the last value * for this attribute?) */ - int flags = BE_INDEX_DEL; - Slapi_Value ** svals = NULL; - Slapi_Value **mods_valueArray = NULL; - - valuearray_init_bervalarray(mods[i]->mod_bvalues, - &mods_valueArray); - - if (slapi_entry_attr_find(newe->ep_entry, - mods[i]->mod_type, &attr) == 0) { - svals = attr_get_present_values(attr); + if (evals == NULL || evals[0] == NULL) { + flags = BE_INDEX_DEL|BE_INDEX_PRESENCE; + } else { + flags = BE_INDEX_DEL; } - if (svals == NULL || svals[0] == NULL) { - flags |= BE_INDEX_PRESENCE; - } + /* If the same value doesn't exist in a subtype, set + * BE_INDEX_EQUALITY flag so the equality index is + * removed. + */ + slapi_entry_attr_find( olde->ep_entry, mods[i]->mod_type, &curr_attr); + if ( valuearray_find(curr_attr, evals, mods_valueArray[i]) == -1 ) { + flags |= BE_INDEX_EQUALITY; + } - rc = index_addordel_values_sv( be, mods[i]->mod_type, + rc = index_addordel_values_sv( be, basetype, mods_valueArray, - svals, id, flags, txn ); - valuearray_free(&mods_valueArray); + evals, id, flags, txn ); } rc = 0; break; } + /* free memory */ + slapi_ch_free((void **)&tmp); + valuearray_free(&mods_valueArray); + slapi_valueset_free(all_vals); + if ( rc != 0 ) { ldbm_nasty(errmsg, 1040, rc); return( rc ); @@ -1595,7 +1722,11 @@ index_addordel_values_ext_sv( /* * equality index entry */ - if ( ai->ai_indexmask & INDEX_EQUALITY ) { + if (( ai->ai_indexmask & INDEX_EQUALITY ) && + (flags & (BE_INDEX_ADD|BE_INDEX_EQUALITY))) { + /* on delete, only remove the equality index if the + * BE_INDEX_EQUALITY flag is set. + */ slapi_call_syntax_values2keys_sv( ai->ai_plugin, vals, &ivals, LDAP_FILTER_EQUALITY ); diff --git a/ldap/servers/slapd/libslapd.def b/ldap/servers/slapd/libslapd.def index 074a8873..cb4b4e77 100644 --- a/ldap/servers/slapd/libslapd.def +++ b/ldap/servers/slapd/libslapd.def @@ -1056,6 +1056,7 @@ EXPORTS slapi_entry_delete_values_sv @1058 slapi_entry_attr_replace_sv @1059 + valuearray_find @1060 valuearray_free @1061 slapd_Client_auth @1062 slapi_rand_r @1063 diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h index 27b5609b..9c9ce5c3 100644 --- a/ldap/servers/slapd/slapi-private.h +++ b/ldap/servers/slapd/slapi-private.h @@ -778,6 +778,7 @@ void valuearray_add_value(Slapi_Value ***vals, const Slapi_Value *addval); void valuearray_add_value_fast(Slapi_Value ***vals, Slapi_Value *addval, int nvals, int *maxvals, int exact, int passin); void valuearray_add_valuearray( Slapi_Value ***vals, Slapi_Value **addvals, PRUint32 flags ); void valuearray_add_valuearray_fast( Slapi_Value ***vals, Slapi_Value **addvals, int nvals, int naddvals, int *maxvals, int exact, int passin ); +int valuearray_find(const Slapi_Attr *a, Slapi_Value **va, const Slapi_Value *v); /****************************************************************************** |