Commit 0ac7618585b1eef3d2280f35513f8e93909feecd

Authored by Wiebe Cazemier
1 parent 4bbc76ec

Use vector for splitting topic path

It's a little faster.
subscriptionstore.cpp
... ... @@ -66,7 +66,7 @@ void SubscriptionStore::publishNonRecursively(const MqttPacket &packet, const st
66 66 }
67 67 }
68 68  
69   -void SubscriptionStore::publishRecursively(std::list<std::string>::const_iterator cur_subtopic_it, std::list<std::string>::const_iterator end,
  69 +void SubscriptionStore::publishRecursively(std::vector<std::string>::const_iterator cur_subtopic_it, std::vector<std::string>::const_iterator end,
70 70 std::unique_ptr<SubscriptionNode> &this_node, const MqttPacket &packet) const
71 71 {
72 72 if (cur_subtopic_it == end) // This is the end of the topic path, so look for subscribers here.
... ... @@ -105,7 +105,7 @@ void SubscriptionStore::queuePacketAtSubscribers(const std::string &amp;topic, const
105 105 {
106 106 // TODO: keep a cache of topics vs clients
107 107  
108   - const std::list<std::string> subtopics = split(topic, '/');
  108 + const std::vector<std::string> subtopics = splitToVector(topic, '/');
109 109  
110 110 RWLockGuard lock_guard(&subscriptionsRwlock);
111 111 lock_guard.rdlock();
... ...
subscriptionstore.h
... ... @@ -43,7 +43,7 @@ class SubscriptionStore
43 43 std::unordered_set<RetainedMessage> retainedMessages;
44 44  
45 45 void publishNonRecursively(const MqttPacket &packet, const std::forward_list<std::string> &subscribers) const;
46   - void publishRecursively(std::list<std::string>::const_iterator cur_subtopic_it, std::list<std::string>::const_iterator end,
  46 + void publishRecursively(std::vector<std::string>::const_iterator cur_subtopic_it, std::vector<std::string>::const_iterator end,
47 47 std::unique_ptr<SubscriptionNode> &next, const MqttPacket &packet) const;
48 48 public:
49 49 SubscriptionStore();
... ...
utils.cpp
... ... @@ -125,3 +125,21 @@ bool isValidPublishPath(const std::string &amp;s)
125 125  
126 126 return true;
127 127 }
  128 +
  129 +std::vector<std::string> splitToVector(const std::string &input, const char sep, size_t max, bool keep_empty_parts)
  130 +{
  131 + std::vector<std::string> list;
  132 + list.reserve(16); // This is somewhat arbitratry, knowing some typical MQTT topic use cases
  133 + size_t start = 0;
  134 + size_t end;
  135 +
  136 + while (list.size() < max && (end = input.find(sep, start)) != std::string::npos)
  137 + {
  138 + if (start != end || keep_empty_parts)
  139 + list.push_back(input.substr(start, end - start));
  140 + start = end + 1; // increase by length of seperator.
  141 + }
  142 + if (start != input.size() || keep_empty_parts)
  143 + list.push_back(input.substr(start, std::string::npos));
  144 + return list;
  145 +}
... ...
... ... @@ -6,6 +6,7 @@
6 6 #include <string>
7 7 #include <list>
8 8 #include <limits>
  9 +#include <vector>
9 10  
10 11 template<typename T> int check(int rc)
11 12 {
... ... @@ -20,6 +21,7 @@ template&lt;typename T&gt; int check(int rc)
20 21 }
21 22  
22 23 std::list<std::string> split(const std::string &input, const char sep, size_t max = std::numeric_limits<int>::max(), bool keep_empty_parts = true);
  24 +std::vector<std::string> splitToVector(const std::string &input, const char sep, size_t max = std::numeric_limits<int>::max(), bool keep_empty_parts = true);
23 25  
24 26 bool topicsMatch(const std::string &subscribeTopic, const std::string &publishTopic);
25 27  
... ...