diff --git a/subscriptionstore.cpp b/subscriptionstore.cpp index 2457d15..42644fb 100644 --- a/subscriptionstore.cpp +++ b/subscriptionstore.cpp @@ -66,7 +66,7 @@ void SubscriptionStore::publishNonRecursively(const MqttPacket &packet, const st } } -void SubscriptionStore::publishRecursively(std::list::const_iterator cur_subtopic_it, std::list::const_iterator end, +void SubscriptionStore::publishRecursively(std::vector::const_iterator cur_subtopic_it, std::vector::const_iterator end, std::unique_ptr &this_node, const MqttPacket &packet) const { 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 &topic, const { // TODO: keep a cache of topics vs clients - const std::list subtopics = split(topic, '/'); + const std::vector subtopics = splitToVector(topic, '/'); RWLockGuard lock_guard(&subscriptionsRwlock); lock_guard.rdlock(); diff --git a/subscriptionstore.h b/subscriptionstore.h index 9f5fc61..6f13f71 100644 --- a/subscriptionstore.h +++ b/subscriptionstore.h @@ -43,7 +43,7 @@ class SubscriptionStore std::unordered_set retainedMessages; void publishNonRecursively(const MqttPacket &packet, const std::forward_list &subscribers) const; - void publishRecursively(std::list::const_iterator cur_subtopic_it, std::list::const_iterator end, + void publishRecursively(std::vector::const_iterator cur_subtopic_it, std::vector::const_iterator end, std::unique_ptr &next, const MqttPacket &packet) const; public: SubscriptionStore(); diff --git a/utils.cpp b/utils.cpp index dec6f8a..898d713 100644 --- a/utils.cpp +++ b/utils.cpp @@ -125,3 +125,21 @@ bool isValidPublishPath(const std::string &s) return true; } + +std::vector splitToVector(const std::string &input, const char sep, size_t max, bool keep_empty_parts) +{ + std::vector list; + list.reserve(16); // This is somewhat arbitratry, knowing some typical MQTT topic use cases + size_t start = 0; + size_t end; + + while (list.size() < max && (end = input.find(sep, start)) != std::string::npos) + { + if (start != end || keep_empty_parts) + list.push_back(input.substr(start, end - start)); + start = end + 1; // increase by length of seperator. + } + if (start != input.size() || keep_empty_parts) + list.push_back(input.substr(start, std::string::npos)); + return list; +} diff --git a/utils.h b/utils.h index 4a5a8c5..af0f0c2 100644 --- a/utils.h +++ b/utils.h @@ -6,6 +6,7 @@ #include #include #include +#include template int check(int rc) { @@ -20,6 +21,7 @@ template int check(int rc) } std::list split(const std::string &input, const char sep, size_t max = std::numeric_limits::max(), bool keep_empty_parts = true); +std::vector splitToVector(const std::string &input, const char sep, size_t max = std::numeric_limits::max(), bool keep_empty_parts = true); bool topicsMatch(const std::string &subscribeTopic, const std::string &publishTopic);