From: Pieter Lexis Date: Tue, 19 Feb 2019 10:37:24 +0000 (+0100) Subject: rec: pre-calculate string for SuffixMatchNode on change X-Git-Tag: rec-4.2.0-beta1~7^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=15d0cc71ce9c8e8d4586c57c642784dad9ce7ba6;p=thirdparty%2Fpdns.git rec: pre-calculate string for SuffixMatchNode on change --- diff --git a/pdns/dnsname.hh b/pdns/dnsname.hh index cb69cac88a..5533da0f60 100644 --- a/pdns/dnsname.hh +++ b/pdns/dnsname.hh @@ -371,49 +371,75 @@ struct SuffixMatchTree anything part of that domain will return 'true' in check */ struct SuffixMatchNode { - SuffixMatchNode() - {} - SuffixMatchTree d_tree; + public: + SuffixMatchNode() + {} + SuffixMatchTree d_tree; + + void add(const DNSName& dnsname) + { + d_tree.add(dnsname, true); + d_nodes.insert(dnsname); + updateHuman(); + } - void add(const DNSName& dnsname) - { - d_tree.add(dnsname, true); - } + void add(std::vector labels) + { + d_tree.add(labels, true); + DNSName tmp; + while (!labels.empty()) { + tmp.appendRawLabel(labels.back()); + labels.pop_back(); // This is safe because we have a copy of labels + } + d_nodes.insert(tmp); + updateHuman(); + } - void add(std::vector labels) - { - d_tree.add(labels, true); - } + void remove(const DNSName& name) + { + d_tree.remove(name); + d_nodes.erase(name); + updateHuman(); + } - void remove(const DNSName& name) - { - d_tree.remove(name); - } + void remove(std::vector labels) + { + d_tree.remove(labels); + DNSName tmp; + while (!labels.empty()) { + tmp.appendRawLabel(labels.back()); + labels.pop_back(); // This is safe because we have a copy of labels + } + d_nodes.erase(tmp); + updateHuman(); + } - void remove(std::vector labels) - { - d_tree.remove(labels); - } + bool check(const DNSName& dnsname) const + { + return d_tree.lookup(dnsname) != nullptr; + } - bool check(const DNSName& dnsname) const - { - return d_tree.lookup(dnsname) != nullptr; - } + std::string toString() const + { + return d_human; + } - std::string toString() const - { - std::string ret; - bool first = true; - for (const auto &n: d_tree.getNodes()) { - if (!first) { - ret += ", "; + private: + mutable std::string d_human; + mutable std::set d_nodes; // Only used for string generation + + void updateHuman() { + std::string tmp; + bool first = true; + for (const auto& n : d_nodes) { + if (!first) { + tmp += ", "; + } + first = false; + tmp += n.toString(); } - first = false; - ret += n.toString(); + d_human = tmp; } - return ret; - } - }; std::ostream & operator<<(std::ostream &os, const DNSName& d);