7#if !defined(ASYNC_MQTT_UTIL_TOPIC_ALIAS_SEND_HPP)
8#define ASYNC_MQTT_UTIL_TOPIC_ALIAS_SEND_HPP
12#include <unordered_map>
17#include <boost/assert.hpp>
18#include <boost/multi_index_container.hpp>
19#include <boost/multi_index/ordered_index.hpp>
20#include <boost/multi_index/key.hpp>
22#include <async_mqtt/util/log.hpp>
23#include <async_mqtt/util/move.hpp>
24#include <async_mqtt/util/value_allocator.hpp>
25#include <async_mqtt/packet/property.hpp>
29namespace mi = boost::multi_index;
31class topic_alias_send {
34 :max_{max}, va_{min_, max_} {}
37 ASYNC_MQTT_LOG(
"mqtt_impl",
trace)
38 << ASYNC_MQTT_ADD_VALUE(address,
this)
39 <<
"topic_alias_send insert"
41 <<
" alias:" << alias;
42 BOOST_ASSERT(!topic.empty() && alias >= min_ && alias <= max_);
44 auto& idx = aliases_.get<tag_alias>();
45 auto it = idx.lower_bound(alias);
46 if (it == idx.end() || it->alias != alias) {
47 idx.emplace_hint(it, std::string(topic), alias, std::chrono::steady_clock::now());
53 e.topic = std::string{topic};
54 e.tp = std::chrono::steady_clock::now();
56 [](
auto&) { BOOST_ASSERT(
false); }
62 ASYNC_MQTT_LOG(
"mqtt_impl",
trace)
63 << ASYNC_MQTT_ADD_VALUE(address,
this)
64 <<
"find_topic_by_alias"
65 <<
" alias:" << alias;
67 if (alias >= min_ && alias <= max_) {
68 auto& idx = aliases_.get<tag_alias>();
69 auto it = idx.find(alias);
70 if (it == idx.end())
return std::string();
75 e.tp = std::chrono::steady_clock::now();
77 [](
auto&) { BOOST_ASSERT(
false); }
85 ASYNC_MQTT_LOG(
"mqtt_impl",
trace)
86 << ASYNC_MQTT_ADD_VALUE(address,
this)
87 <<
"find_topic_by_alias"
88 <<
" alias:" << alias;
90 if (alias >= min_ && alias <= max_) {
91 auto& idx = aliases_.get<tag_alias>();
92 auto it = idx.find(alias);
93 if (it == idx.end())
return std::string();
99 std::optional<topic_alias_type> find(std::string_view topic)
const {
100 ASYNC_MQTT_LOG(
"mqtt_impl",
trace)
101 << ASYNC_MQTT_ADD_VALUE(address,
this)
102 <<
"find_alias_by_topic"
103 <<
" topic:" << topic;
105 auto& idx = aliases_.get<tag_topic_name>();
106 auto it = idx.find(topic);
107 if (it == idx.end())
return std::nullopt;
112 ASYNC_MQTT_LOG(
"mqtt_impl",
info)
113 << ASYNC_MQTT_ADD_VALUE(address,
this)
114 <<
"clear_topic_alias";
120 BOOST_ASSERT(max_ > 0);
121 if (
auto alias_opt = va_.first_vacant()) {
124 auto& idx = aliases_.get<tag_tp>();
125 return idx.begin()->alias;
135 entry(std::string topic,
topic_alias_type alias, std::chrono::time_point<std::chrono::steady_clock> tp)
136 : topic{force_move(topic)}, alias{alias}, tp{force_move(tp)} {}
138 std::string_view get_topic_as_view()
const {
144 std::chrono::time_point<std::chrono::steady_clock> tp;
148 struct tag_topic_name {};
149 using mi_topic_alias = mi::multi_index_container<
154 mi::key<&entry::alias>
157 mi::tag<tag_topic_name>,
158 mi::key<&entry::get_topic_as_view>
160 mi::ordered_non_unique<
167 mi_topic_alias aliases_;
168 value_allocator<topic_alias_type> va_;
@ trace
trace level for detaied behavior and reporting issue
@ info
info level api call is output
std::uint16_t topic_alias_type
type of the topic alias value
Definition property.hpp:81