Skip to content

Commit

Permalink
Issue 6172 - RFE: improve the performance of evaluation of filter com…
Browse files Browse the repository at this point in the history
…ponent when tested against a large valueset (like group members)

Bug description:
Before returning an entry (to a SRCH) the server checks that the entry matches the SRCH filter.
If a filter component (equality) is testing the value (ava) against a
large valueset (like uniquemember values), it takes a long time because
of large number of value and required normalization of the values.
This can be improved taking benefit of sorted valueset. Those sorted
valueset were created to improve updates of large valueset (groups) but
not used in SRCH path.

Fix description:
if config param 'nsslapd-filter-match-use-sorted-vs = on' then it uses
slapi_valueset_find (that tries to use sorted valueset) rather than
plugin_call_syntax_filter_ava.
In both case sorted valueset and plugin_call_syntax_filter_ava, ava and
values are normalized.
In sorted valueset, the values have been normalized to insert the index
in the sorted array and then comparison is done on normalized values.
In plugin_call_syntax_filter_ava, all values in valuearray (of valueset) are normalized
before comparison.

Likely this optimization should be dropped for extended search

relates: 389ds#6172

Reviewed by:
  • Loading branch information
tbordaz committed May 15, 2024
1 parent 884deb6 commit 97e04e9
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 1 deletion.
19 changes: 18 additions & 1 deletion ldap/servers/slapd/filterentry.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,24 @@ test_ava_filter(
rc = -1;
for (; a != NULL; a = a->a_next) {
if (slapi_attr_type_cmp(ava->ava_type, a->a_type, SLAPI_TYPE_CMP_SUBTYPE) == 0) {
rc = plugin_call_syntax_filter_ava(a, ftype, ava);
if (config_get_filter_match_use_sorted_vs()) {
/* retrieve the ava value from the valuearray
* and potentially get benefit of sorted valuearray
* within the valueset
*/
Slapi_Value *sval = NULL;
sval = slapi_value_new_berval(&ava->ava_value);
if (slapi_valueset_find((const Slapi_Attr *)a, &a->a_present_values, sval)) {
rc = 0;
}
slapi_value_free(&sval);
} else {
/* else use the original access that uses
* the directly the valuearray without taking
* into account the potentially sorted valueset
*/
rc = plugin_call_syntax_filter_ava(a, ftype, ava);
}
if (rc == 0) {
break;
}
Expand Down
31 changes: 31 additions & 0 deletions ldap/servers/slapd/libglobs.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ slapi_onoff_t init_accesscontrol;
slapi_onoff_t init_nagle;
slapi_onoff_t init_security;
slapi_onoff_t init_ssl_check_hostname;
slapi_onoff_t init_filter_match_use_sorted_vs;
slapi_onoff_t init_ldapi_switch;
slapi_onoff_t init_ldapi_bind_switch;
slapi_onoff_t init_ldapi_map_entries;
Expand Down Expand Up @@ -1013,6 +1014,10 @@ static struct config_get_and_set
NULL, 0, NULL,
CONFIG_ON_OFF, (ConfigGetFunc)config_get_hash_filters,
NULL, NULL /* deletion is not allowed */},
{CONFIG_FILTER_MATCH_USE_SORTED_VS, config_set_filter_match_use_sorted_vs,
NULL, 0,
(void **)&global_slapdFrontendConfig.filter_match_use_sorted_vs,
CONFIG_ON_OFF, NULL, &init_filter_match_use_sorted_vs, NULL /* deletion is not allowed */},
/* instance dir; used by admin tasks */
{CONFIG_INSTDIR_ATTRIBUTE, config_set_instancedir,
NULL, 0,
Expand Down Expand Up @@ -1838,6 +1843,7 @@ FrontendConfig_init(void)
init_enquote_sup_oc = cfg->enquote_sup_oc = LDAP_OFF;
init_lastmod = cfg->lastmod = LDAP_ON;
init_rewrite_rfc1274 = cfg->rewrite_rfc1274 = LDAP_OFF;
init_filter_match_use_sorted_vs = cfg->filter_match_use_sorted_vs = LDAP_OFF;
cfg->schemareplace = slapi_ch_strdup(CONFIG_SCHEMAREPLACE_STR_REPLICATION_ONLY);
init_schema_ignore_trailing_spaces = cfg->schema_ignore_trailing_spaces =
SLAPD_DEFAULT_SCHEMA_IGNORE_TRAILING_SPACES;
Expand Down Expand Up @@ -7885,6 +7891,31 @@ config_set_hash_filters(const char *attrname, char *value, char *errorbuf, int a
return retVal;
}

int32_t
config_set_filter_match_use_sorted_vs(const char *attrname, char *value, char *errorbuf, int apply)
{
int32_t retVal = LDAP_SUCCESS;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();

retVal = config_set_onoff(attrname,
value,
&(slapdFrontendConfig->filter_match_use_sorted_vs),
errorbuf,
apply);

return retVal;
}

int
config_get_filter_match_use_sorted_vs()
{
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
int retVal;

retVal = (int)slapdFrontendConfig->filter_match_use_sorted_vs;
return retVal;
}

int
config_get_hash_filters()
{
Expand Down
2 changes: 2 additions & 0 deletions ldap/servers/slapd/proto-slap.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ int config_set_rundir(const char *attrname, char *value, char *errorbuf, int app
int config_set_saslpath(const char *attrname, char *value, char *errorbuf, int apply);
int config_set_attrname_exceptions(const char *attrname, char *value, char *errorbuf, int apply);
int config_set_hash_filters(const char *attrname, char *value, char *errorbuf, int apply);
int32_t config_set_filter_match_use_sorted_vs(const char *attrname, char *value, char *errorbuf, int apply);
int config_set_rewrite_rfc1274(const char *attrname, char *value, char *errorbuf, int apply);
int config_set_outbound_ldap_io_timeout(const char *attrname, char *value, char *errorbuf, int apply);
int config_set_unauth_binds_switch(const char *attrname, char *value, char *errorbuf, int apply);
Expand Down Expand Up @@ -550,6 +551,7 @@ char **config_get_auditlog_list(void);
char **config_get_auditfaillog_list(void);
int config_get_attrname_exceptions(void);
int config_get_hash_filters(void);
int config_get_filter_match_use_sorted_vs();

Check warning on line 554 in ldap/servers/slapd/proto-slap.h

View workflow job for this annotation

GitHub Actions / compile (GCC Strict)

function declaration isn't a prototype [-Wstrict-prototypes]

Check warning on line 554 in ldap/servers/slapd/proto-slap.h

View workflow job for this annotation

GitHub Actions / compile (GCC Strict)

function declaration isn't a prototype [-Wstrict-prototypes]
int config_get_rewrite_rfc1274(void);
int config_get_outbound_ldap_io_timeout(void);
int config_get_unauth_binds_switch(void);
Expand Down
2 changes: 2 additions & 0 deletions ldap/servers/slapd/slap.h
Original file line number Diff line number Diff line change
Expand Up @@ -2340,6 +2340,7 @@ typedef struct _slapdEntryPoints
#define CONFIG_SSL_CHECK_HOSTNAME_ATTRIBUTE "nsslapd-ssl-check-hostname"
#define CONFIG_TLS_CHECK_CRL_ATTRIBUTE "nsslapd-tls-check-crl"
#define CONFIG_HASH_FILTERS_ATTRIBUTE "nsslapd-hash-filters"
#define CONFIG_FILTER_MATCH_USE_SORTED_VS "nsslapd-filter-match-use-sorted-vs"
#define CONFIG_OUTBOUND_LDAP_IO_TIMEOUT_ATTRIBUTE "nsslapd-outbound-ldap-io-timeout"
#define CONFIG_FORCE_SASL_EXTERNAL_ATTRIBUTE "nsslapd-force-sasl-external"
#define CONFIG_ENTRYUSN_GLOBAL "nsslapd-entryusn-global"
Expand Down Expand Up @@ -2726,6 +2727,7 @@ typedef struct _slapdFrontendConfig
slapi_onoff_t return_orig_dn;
slapi_onoff_t pw_admin_skip_info;
char *auditlog_display_attrs;
slapi_onoff_t filter_match_use_sorted_vs;
} slapdFrontendConfig_t;

/* possible values for slapdFrontendConfig_t.schemareplace */
Expand Down

0 comments on commit 97e04e9

Please sign in to comment.