Skip to content

Commit dfcb27e

Browse files
committed
[http_server] Use classic impl wrapper to have one shared_ptr
...other than shared_ptr everywhere on each small drt_node objects.
1 parent 31b2024 commit dfcb27e

File tree

1 file changed

+52
-19
lines changed

1 file changed

+52
-19
lines changed

libraries/http_server/http_server/dynamic_routing_table.hh

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,21 @@ namespace li {
1111

1212
namespace internal {
1313

14-
template <typename V> struct drt_node {
14+
// A simple memory pool for drt_node objects
15+
template <typename T> struct drt_node_pool {
16+
template <typename... Args> T* allocate(Args&&... args) {
17+
auto new_node = std::make_unique<T>(std::forward<Args>(args)...);
18+
T* ptr = new_node.get();
19+
pool_.emplace_back(std::move(new_node));
20+
return ptr;
21+
}
22+
23+
std::vector<std::unique_ptr<T>> pool_;
24+
};
1525

16-
drt_node() : v_{0, nullptr} {}
26+
template <typename V> struct drt_node {
27+
drt_node() : pool_(nullptr), v_{0, nullptr} {}
28+
drt_node(drt_node_pool<drt_node>& pool) : pool_(pool), v_{0, nullptr} {}
1729

1830
struct iterator {
1931
const drt_node<V>* ptr;
@@ -38,17 +50,10 @@ template <typename V> struct drt_node {
3850
c++;
3951
std::string_view k = r.substr(s, c - s);
4052

41-
auto it = children_.find(k);
42-
if (it != children_.end())
43-
return children_[k]->find_or_create(r, c);
44-
else {
45-
auto new_node = std::make_shared<drt_node>();
46-
children_shared_pointers_.push_back(new_node);
47-
children_.insert({k, new_node.get()});
48-
return new_node->find_or_create(r, c);
53+
if (children_.find(k) == children_.end()) {
54+
children_[k] = pool_.allocate(pool_);
4955
}
50-
51-
return v_;
56+
return children_[k]->find_or_create(r, c);
5257
}
5358

5459
template <typename F> void for_all_routes(F f, std::string prefix = "") const {
@@ -57,8 +62,8 @@ template <typename V> struct drt_node {
5762
else {
5863
if (prefix.size() && prefix.back() != '/')
5964
prefix += '/';
60-
for (auto pair : children_)
61-
pair.second->for_all_routes(f, prefix + std::string(pair.first));
65+
for (const auto& kv : children_)
66+
kv.second->for_all_routes(f, prefix + std::string(kv.first));
6267
}
6368
}
6469

@@ -95,7 +100,7 @@ template <typename V> struct drt_node {
95100

96101
{
97102
// if one child is a url param {{param_name}}, choose it
98-
for (auto& kv : children_) {
103+
for (const auto& kv : children_) {
99104
auto name = kv.first;
100105
if (name.size() > 4 and name[0] == '{' and name[1] == '{' and
101106
name[name.size() - 2] == '}' and name[name.size() - 1] == '}')
@@ -107,11 +112,11 @@ template <typename V> struct drt_node {
107112

108113
V v_;
109114
std::unordered_map<std::string_view, drt_node*> children_;
110-
std::vector<std::shared_ptr<drt_node>> children_shared_pointers_;
115+
drt_node_pool<drt_node>& pool_;
111116
};
112-
} // namespace internal
113117

114-
template <typename V> struct dynamic_routing_table {
118+
template <typename V> struct dynamic_routing_table_impl {
119+
dynamic_routing_table_impl() : root(pool) {}
115120

116121
// Find a route and return reference to a procedure.
117122
auto& operator[](const std::string_view& r) {
@@ -132,7 +137,35 @@ template <typename V> struct dynamic_routing_table {
132137
auto end() const { return root.end(); }
133138

134139
std::unordered_set<std::string> strings;
135-
internal::drt_node<V> root;
140+
drt_node_pool<drt_node<V>> pool;
141+
drt_node<V> root;
142+
};
143+
} // namespace internal
144+
145+
template <typename V> struct dynamic_routing_table {
146+
dynamic_routing_table() : impl_(std::make_shared<internal::dynamic_routing_table_impl<V>>()) {}
147+
dynamic_routing_table(const dynamic_routing_table& other) : impl_(other.impl_) {}
148+
149+
// Assignment operator
150+
dynamic_routing_table& operator=(const dynamic_routing_table& other) {
151+
if (this != &other) {
152+
impl_ = other.impl_;
153+
}
154+
return *this;
155+
}
156+
157+
// Find a route and return reference to a procedure.
158+
auto& operator[](const std::string_view& r) { return impl_->operator[](r); }
159+
auto& operator[](const std::string& s) { return impl_->operator[](s); }
160+
161+
// Find a route and return an iterator.
162+
auto find(const std::string_view& r) const { return impl_->find(r); }
163+
164+
template <typename F> void for_all_routes(F f) const { impl_->for_all_routes(f); }
165+
auto end() const { return impl_->end(); }
166+
167+
private:
168+
std::shared_ptr<internal::dynamic_routing_table_impl<V>> impl_;
136169
};
137170

138171
} // namespace li

0 commit comments

Comments
 (0)