]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: pre-calculate string for SuffixMatchNode on change
authorPieter Lexis <pieter.lexis@powerdns.com>
Tue, 19 Feb 2019 10:37:24 +0000 (11:37 +0100)
committerPieter Lexis <pieter.lexis@powerdns.com>
Tue, 19 Feb 2019 10:37:24 +0000 (11:37 +0100)
pdns/dnsname.hh

index cb69cac88a95b1de860ed9a33bb1c5434365b1fd..5533da0f600ef71873a9426deec891d9eac8b8a0 100644 (file)
@@ -371,49 +371,75 @@ struct SuffixMatchTree
    anything part of that domain will return 'true' in check */
 struct SuffixMatchNode
 {
-  SuffixMatchNode()
-  {}
-  SuffixMatchTree<bool> d_tree;
+  public:
+    SuffixMatchNode()
+    {}
+    SuffixMatchTree<bool> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<DNSName> 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);