From: Douglas Bagnall Date: Thu, 17 Oct 2024 02:54:22 +0000 (+1300) Subject: libndr: specialise ndr_token_find() for key pointer comparison X-Git-Tag: tdb-1.4.13~645 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=982042115b1709b914fd0325f764edca0857d84b;p=thirdparty%2Fsamba.git libndr: specialise ndr_token_find() for key pointer comparison Usually we are doing a pointer comparison. Because we are doing it in a tight loop, the cost of the comparison function call can be noticeable. There is a fuzz case that before f43ae1ab1a8803d8c5ad4e5f3dad63ccbe91aa54 took 3.957s, after that took 6.438s, and now again takes 3.960s. Signed-off-by: Douglas Bagnall Reviewed-by: Volker Lendecke Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Wed Nov 6 12:06:04 UTC 2024 on atb-devel-224 --- diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c index 1916b6db7b8..e552ccba20f 100644 --- a/librpc/ndr/ndr.c +++ b/librpc/ndr/ndr.c @@ -1062,6 +1062,27 @@ static enum ndr_err_code ndr_token_find(struct ndr_token_list *list, return NDR_ERR_TOKEN; } +/* + * retrieve a token from a ndr context, matching by key address. + */ +static enum ndr_err_code ndr_token_find_by_key_address(struct ndr_token_list *list, + const void *key, + uint32_t *v, + unsigned *_i) +{ + struct ndr_token *tokens = list->tokens; + unsigned i; + for (i = list->count - 1; i < list->count; i--) { + if (tokens[i].key == key) { + *_i = i; + *v = tokens[i].value; + return NDR_ERR_SUCCESS; + } + } + return NDR_ERR_TOKEN; +} + + _PUBLIC_ enum ndr_err_code ndr_token_peek_cmp_fn(struct ndr_token_list *list, const void *key, uint32_t *v, @@ -1071,11 +1092,6 @@ _PUBLIC_ enum ndr_err_code ndr_token_peek_cmp_fn(struct ndr_token_list *list, return ndr_token_find(list, key, v, _cmp_fn, &i); } -static int token_cmp_ptr(const void *a, const void *b) -{ - return (a == b) ? 0 : 1; -} - /* retrieve a token from a ndr context */ @@ -1086,7 +1102,7 @@ _PUBLIC_ enum ndr_err_code ndr_token_retrieve(struct ndr_token_list *list, uint32_t last; unsigned i; - err = ndr_token_find(list, key, v, token_cmp_ptr, &i); + err = ndr_token_find_by_key_address(list, key, v, &i); if (!NDR_ERR_CODE_IS_SUCCESS(err)) { return err; } @@ -1107,7 +1123,7 @@ _PUBLIC_ enum ndr_err_code ndr_token_peek(struct ndr_token_list *list, const void *key, uint32_t *v) { unsigned i; - return ndr_token_find(list, key, v, token_cmp_ptr, &i); + return ndr_token_find_by_key_address(list, key, v, &i); } /*