]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
libndr: specialise ndr_token_find() for key pointer comparison
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Thu, 17 Oct 2024 02:54:22 +0000 (15:54 +1300)
committerVolker Lendecke <vl@samba.org>
Wed, 6 Nov 2024 12:06:04 +0000 (12:06 +0000)
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 <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Volker Lendecke <vl@samba.org>
Autobuild-User(master): Volker Lendecke <vl@samba.org>
Autobuild-Date(master): Wed Nov  6 12:06:04 UTC 2024 on atb-devel-224

librpc/ndr/ndr.c

index 1916b6db7b84400585a342f9951fa4e3f6890973..e552ccba20f80463352046148d56c5ef6b8953a2 100644 (file)
@@ -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);
 }
 
 /*