@@ -11,9 +11,21 @@ namespace li {
1111
1212namespace 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