Commit 4ee428385ba8ab278da0c2db68a17af510a039df

Authored by Wiebe Cazemier
1 parent 0ac76185

Optimize by having seperate leafs for + and #

This saves mildly costly calls to find().
subscriptionstore.cpp
@@ -28,8 +28,16 @@ void SubscriptionStore::addSubscription(Client_p &client, const std::string &top @@ -28,8 +28,16 @@ void SubscriptionStore::addSubscription(Client_p &client, const std::string &top
28 SubscriptionNode *deepestNode = root.get(); 28 SubscriptionNode *deepestNode = root.get();
29 for(const std::string &subtopic : subtopics) 29 for(const std::string &subtopic : subtopics)
30 { 30 {
31 - SubscriptionNode &nodeRef = *deepestNode;  
32 - std::unique_ptr<SubscriptionNode> &node = nodeRef.children[subtopic]; 31 + std::unique_ptr<SubscriptionNode> *selectedChildren = nullptr;
  32 +
  33 + if (subtopic == "#")
  34 + selectedChildren = &deepestNode->childrenPound;
  35 + else if (subtopic == "+")
  36 + selectedChildren = &deepestNode->childrenPlus;
  37 + else
  38 + selectedChildren = &deepestNode->children[subtopic];
  39 +
  40 + std::unique_ptr<SubscriptionNode> &node = *selectedChildren;
33 41
34 if (!node) 42 if (!node)
35 { 43 {
@@ -75,17 +83,16 @@ void SubscriptionStore::publishRecursively(std::vector&lt;std::string&gt;::const_itera @@ -75,17 +83,16 @@ void SubscriptionStore::publishRecursively(std::vector&lt;std::string&gt;::const_itera
75 return; 83 return;
76 } 84 }
77 85
78 - if (this_node->children.empty()) 86 + if (this_node->children.empty() && !this_node->childrenPlus && !this_node->childrenPound)
79 return; 87 return;
80 88
81 std::string cur_subtop = *cur_subtopic_it; 89 std::string cur_subtop = *cur_subtopic_it;
82 90
83 const auto next_subtopic = ++cur_subtopic_it; 91 const auto next_subtopic = ++cur_subtopic_it;
84 92
85 - const auto pound_sign_node = this_node->children.find("#");  
86 - if (pound_sign_node != this_node->children.end()) 93 + if (this_node->childrenPound)
87 { 94 {
88 - publishNonRecursively(packet, pound_sign_node->second->subscribers); 95 + publishNonRecursively(packet, this_node->childrenPound->subscribers);
89 } 96 }
90 97
91 auto sub_node = this_node->children.find(cur_subtop); 98 auto sub_node = this_node->children.find(cur_subtop);
@@ -94,10 +101,9 @@ void SubscriptionStore::publishRecursively(std::vector&lt;std::string&gt;::const_itera @@ -94,10 +101,9 @@ void SubscriptionStore::publishRecursively(std::vector&lt;std::string&gt;::const_itera
94 publishRecursively(next_subtopic, end, sub_node->second, packet); 101 publishRecursively(next_subtopic, end, sub_node->second, packet);
95 } 102 }
96 103
97 - const auto plus_sign_node = this_node->children.find("+");  
98 - if (plus_sign_node != this_node->children.end()) 104 + if (this_node->childrenPlus)
99 { 105 {
100 - publishRecursively(next_subtopic, end, plus_sign_node->second, packet); 106 + publishRecursively(next_subtopic, end, this_node->childrenPlus, packet);
101 } 107 }
102 } 108 }
103 109
subscriptionstore.h
@@ -30,6 +30,8 @@ public: @@ -30,6 +30,8 @@ public:
30 30
31 std::forward_list<std::string> subscribers; // The idea is to store subscriptions by client id, to support persistent sessions. 31 std::forward_list<std::string> subscribers; // The idea is to store subscriptions by client id, to support persistent sessions.
32 std::unordered_map<std::string, std::unique_ptr<SubscriptionNode>> children; 32 std::unordered_map<std::string, std::unique_ptr<SubscriptionNode>> children;
  33 + std::unique_ptr<SubscriptionNode> childrenPlus;
  34 + std::unique_ptr<SubscriptionNode> childrenPound;
33 }; 35 };
34 36
35 class SubscriptionStore 37 class SubscriptionStore