@@ -11,9 +11,21 @@ namespace li {
11
11
12
12
namespace internal {
13
13
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
+ };
15
25
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 } {}
17
29
18
30
struct iterator {
19
31
const drt_node<V>* ptr;
@@ -38,17 +50,10 @@ template <typename V> struct drt_node {
38
50
c++;
39
51
std::string_view k = r.substr (s, c - s);
40
52
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_);
49
55
}
50
-
51
- return v_;
56
+ return children_[k]->find_or_create (r, c);
52
57
}
53
58
54
59
template <typename F> void for_all_routes (F f, std::string prefix = " " ) const {
@@ -57,8 +62,8 @@ template <typename V> struct drt_node {
57
62
else {
58
63
if (prefix.size () && prefix.back () != ' /' )
59
64
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 ));
62
67
}
63
68
}
64
69
@@ -95,7 +100,7 @@ template <typename V> struct drt_node {
95
100
96
101
{
97
102
// if one child is a url param {{param_name}}, choose it
98
- for (auto & kv : children_) {
103
+ for (const auto & kv : children_) {
99
104
auto name = kv.first ;
100
105
if (name.size () > 4 and name[0 ] == ' {' and name[1 ] == ' {' and
101
106
name[name.size () - 2 ] == ' }' and name[name.size () - 1 ] == ' }' )
@@ -107,11 +112,11 @@ template <typename V> struct drt_node {
107
112
108
113
V v_;
109
114
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_ ;
111
116
};
112
- } // namespace internal
113
117
114
- template <typename V> struct dynamic_routing_table {
118
+ template <typename V> struct dynamic_routing_table_impl {
119
+ dynamic_routing_table_impl () : root(pool) {}
115
120
116
121
// Find a route and return reference to a procedure.
117
122
auto & operator [](const std::string_view& r) {
@@ -132,7 +137,35 @@ template <typename V> struct dynamic_routing_table {
132
137
auto end () const { return root.end (); }
133
138
134
139
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_;
136
169
};
137
170
138
171
} // namespace li
0 commit comments