]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: use a temporary Set to speed up dns question parsing
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 27 Feb 2019 06:01:50 +0000 (07:01 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 4 Mar 2019 14:53:37 +0000 (15:53 +0100)
This doesn't necessarily make things faster, because we still spend more time
in dns_answer_add(), but it improves the compuational complexity of this part.
If we even make dns_resource_key_equal_faster, this will become worthwhile.

src/resolve/resolved-dns-packet.c
src/resolve/resolved-dns-question.c
src/resolve/resolved-dns-question.h

index 572271be95c37c8ebd1338eb4f52bd88bb4043a0..ff58a9d810143e2f74108ad818d4c4f43cbff458 100644 (file)
@@ -7,6 +7,7 @@
 #include "alloc-util.h"
 #include "dns-domain.h"
 #include "resolved-dns-packet.h"
+#include "set.h"
 #include "string-table.h"
 #include "strv.h"
 #include "unaligned.h"
@@ -2133,6 +2134,17 @@ static int dns_packet_extract_question(DnsPacket *p, DnsQuestion **ret_question)
                 if (!question)
                         return -ENOMEM;
 
+                _cleanup_set_free_ Set *keys = NULL; /* references to keys are kept by Question */
+
+                keys = set_new(&dns_resource_key_hash_ops);
+                if (!keys)
+                        return log_oom();
+
+                r = set_reserve(keys, n * 2); /* Higher multipliers give slightly higher efficiency through
+                                               * hash collisions, but the gains quickly drop of after 2. */
+                if (r < 0)
+                        return r;
+
                 for (i = 0; i < n; i++) {
                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
                         bool cache_flush;
@@ -2147,7 +2159,14 @@ static int dns_packet_extract_question(DnsPacket *p, DnsQuestion **ret_question)
                         if (!dns_type_is_valid_query(key->type))
                                 return -EBADMSG;
 
-                        r = dns_question_add(question, key);
+                        r = set_put(keys, key);
+                        if (r < 0)
+                                return r;
+                        if (r == 0)
+                                /* Already in the Question, let's skip */
+                                continue;
+
+                        r = dns_question_add_raw(question, key);
                         if (r < 0)
                                 return r;
                 }
index 1ed9171564a5c2bb572152a40fb5b700d5aa1ff5..60cd34bcfc1d5677e4f3f46fe010ba2d55386055 100644 (file)
@@ -32,8 +32,20 @@ static DnsQuestion *dns_question_free(DnsQuestion *q) {
 
 DEFINE_TRIVIAL_REF_UNREF_FUNC(DnsQuestion, dns_question, dns_question_free);
 
+int dns_question_add_raw(DnsQuestion *q, DnsResourceKey *key) {
+        /* Insert without checking for duplicates. */
+
+        assert(key);
+        assert(q);
+
+        if (q->n_keys >= q->n_allocated)
+                return -ENOSPC;
+
+        q->keys[q->n_keys++] = dns_resource_key_ref(key);
+        return 0;
+}
+
 int dns_question_add(DnsQuestion *q, DnsResourceKey *key) {
-        size_t i;
         int r;
 
         assert(key);
@@ -41,7 +53,7 @@ int dns_question_add(DnsQuestion *q, DnsResourceKey *key) {
         if (!q)
                 return -ENOSPC;
 
-        for (i = 0; i < q->n_keys; i++) {
+        for (size_t i = 0; i < q->n_keys; i++) {
                 r = dns_resource_key_equal(q->keys[i], key);
                 if (r < 0)
                         return r;
@@ -49,11 +61,7 @@ int dns_question_add(DnsQuestion *q, DnsResourceKey *key) {
                         return 0;
         }
 
-        if (q->n_keys >= q->n_allocated)
-                return -ENOSPC;
-
-        q->keys[q->n_keys++] = dns_resource_key_ref(key);
-        return 0;
+        return dns_question_add_raw(q, key);
 }
 
 int dns_question_matches_rr(DnsQuestion *q, DnsResourceRecord *rr, const char *search_domain) {
index f513bf03282634da3fb05528c0f718a62378849a..0803f49b8bb1c8f5eb713d782384bfe0eff61e52 100644 (file)
@@ -22,6 +22,7 @@ int dns_question_new_address(DnsQuestion **ret, int family, const char *name, bo
 int dns_question_new_reverse(DnsQuestion **ret, int family, const union in_addr_union *a);
 int dns_question_new_service(DnsQuestion **ret, const char *service, const char *type, const char *domain, bool with_txt, bool convert_idna);
 
+int dns_question_add_raw(DnsQuestion *q, DnsResourceKey *key);
 int dns_question_add(DnsQuestion *q, DnsResourceKey *key);
 
 int dns_question_matches_rr(DnsQuestion *q, DnsResourceRecord *rr, const char *search_domain);