From 9db72df4b1537652481a92f4be7e8b13b6528cc1 Mon Sep 17 00:00:00 2001 From: cong1920 Date: Mon, 30 Dec 2024 23:49:27 -0800 Subject: [PATCH] [single_headers] Add the generated files --- single_headers/lithium.hh | 86 +++++++++++++++++++-------- single_headers/lithium_http_server.hh | 86 +++++++++++++++++++-------- single_headers/lithium_mysql.hh | 1 + single_headers/lithium_pgsql.hh | 1 + 4 files changed, 122 insertions(+), 52 deletions(-) diff --git a/single_headers/lithium.hh b/single_headers/lithium.hh index 9e0139d..1b3229c 100644 --- a/single_headers/lithium.hh +++ b/single_headers/lithium.hh @@ -73,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -6510,9 +6511,21 @@ namespace li { namespace internal { -template struct drt_node { +// A simple memory pool for drt_node objects +template struct drt_node_pool { + template T* allocate(Args&&... args) { + auto new_node = std::make_unique(std::forward(args)...); + T* ptr = new_node.get(); + pool_.emplace_back(std::move(new_node)); + return ptr; + } - drt_node() : v_{0, nullptr} {} + std::vector> pool_; +}; + +template struct drt_node { + drt_node() : pool_(nullptr), v_{0, nullptr} {} + drt_node(drt_node_pool& pool) : pool_(pool), v_{0, nullptr} {} struct iterator { const drt_node* ptr; @@ -6537,17 +6550,10 @@ template struct drt_node { c++; std::string_view k = r.substr(s, c - s); - auto it = children_.find(k); - if (it != children_.end()) - return children_[k]->find_or_create(r, c); - else { - auto new_node = std::make_shared(); - children_shared_pointers_.push_back(new_node); - children_.insert({k, new_node.get()}); - return new_node->find_or_create(r, c); + if (children_.find(k) == children_.end()) { + children_[k] = pool_.allocate(pool_); } - - return v_; + return children_[k]->find_or_create(r, c); } template void for_all_routes(F f, std::string prefix = "") const { @@ -6556,8 +6562,8 @@ template struct drt_node { else { if (prefix.size() && prefix.back() != '/') prefix += '/'; - for (auto pair : children_) - pair.second->for_all_routes(f, prefix + std::string(pair.first)); + for (const auto& kv : children_) + kv.second->for_all_routes(f, prefix + std::string(kv.first)); } } @@ -6594,7 +6600,7 @@ template struct drt_node { { // if one child is a url param {{param_name}}, choose it - for (auto& kv : children_) { + for (const auto& kv : children_) { auto name = kv.first; if (name.size() > 4 and name[0] == '{' and name[1] == '{' and name[name.size() - 2] == '}' and name[name.size() - 1] == '}') @@ -6606,22 +6612,22 @@ template struct drt_node { V v_; std::unordered_map children_; - std::vector> children_shared_pointers_; + drt_node_pool& pool_; }; -} // namespace internal -template struct dynamic_routing_table { +template struct dynamic_routing_table_impl { + dynamic_routing_table_impl() : root(pool) {} // Find a route and return reference to a procedure. auto& operator[](const std::string_view& r) { - strings.push_back(std::make_shared(r)); - std::string_view r2(*strings.back()); + auto [itr, is_inserted] = strings.emplace(std::string(r)); + std::string_view r2(*itr); return root.find_or_create(r2, 0); } - auto& operator[](const std::string& r) { - strings.push_back(std::make_shared(r)); - std::string_view r2(*strings.back()); - return root.find_or_create(r2, 0); + auto& operator[](const std::string& s) { + auto [itr, is_inserted] = strings.emplace(s); + std::string_view r(*itr); + return root.find_or_create(r, 0); } // Find a route and return an iterator. @@ -6630,8 +6636,36 @@ template struct dynamic_routing_table { template void for_all_routes(F f) const { root.for_all_routes(f); } auto end() const { return root.end(); } - std::vector> strings; - internal::drt_node root; + std::unordered_set strings; + drt_node_pool> pool; + drt_node root; +}; +} // namespace internal + +template struct dynamic_routing_table { + dynamic_routing_table() : impl_(std::make_shared>()) {} + dynamic_routing_table(const dynamic_routing_table& other) : impl_(other.impl_) {} + + // Assignment operator + dynamic_routing_table& operator=(const dynamic_routing_table& other) { + if (this != &other) { + impl_ = other.impl_; + } + return *this; + } + + // Find a route and return reference to a procedure. + auto& operator[](const std::string_view& r) { return impl_->operator[](r); } + auto& operator[](const std::string& s) { return impl_->operator[](s); } + + // Find a route and return an iterator. + auto find(const std::string_view& r) const { return impl_->find(r); } + + template void for_all_routes(F f) const { impl_->for_all_routes(f); } + auto end() const { return impl_->end(); } + + private: + std::shared_ptr> impl_; }; } // namespace li diff --git a/single_headers/lithium_http_server.hh b/single_headers/lithium_http_server.hh index 1266d16..844e604 100644 --- a/single_headers/lithium_http_server.hh +++ b/single_headers/lithium_http_server.hh @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -3330,9 +3331,21 @@ namespace li { namespace internal { -template struct drt_node { +// A simple memory pool for drt_node objects +template struct drt_node_pool { + template T* allocate(Args&&... args) { + auto new_node = std::make_unique(std::forward(args)...); + T* ptr = new_node.get(); + pool_.emplace_back(std::move(new_node)); + return ptr; + } - drt_node() : v_{0, nullptr} {} + std::vector> pool_; +}; + +template struct drt_node { + drt_node() : pool_(nullptr), v_{0, nullptr} {} + drt_node(drt_node_pool& pool) : pool_(pool), v_{0, nullptr} {} struct iterator { const drt_node* ptr; @@ -3357,17 +3370,10 @@ template struct drt_node { c++; std::string_view k = r.substr(s, c - s); - auto it = children_.find(k); - if (it != children_.end()) - return children_[k]->find_or_create(r, c); - else { - auto new_node = std::make_shared(); - children_shared_pointers_.push_back(new_node); - children_.insert({k, new_node.get()}); - return new_node->find_or_create(r, c); + if (children_.find(k) == children_.end()) { + children_[k] = pool_.allocate(pool_); } - - return v_; + return children_[k]->find_or_create(r, c); } template void for_all_routes(F f, std::string prefix = "") const { @@ -3376,8 +3382,8 @@ template struct drt_node { else { if (prefix.size() && prefix.back() != '/') prefix += '/'; - for (auto pair : children_) - pair.second->for_all_routes(f, prefix + std::string(pair.first)); + for (const auto& kv : children_) + kv.second->for_all_routes(f, prefix + std::string(kv.first)); } } @@ -3414,7 +3420,7 @@ template struct drt_node { { // if one child is a url param {{param_name}}, choose it - for (auto& kv : children_) { + for (const auto& kv : children_) { auto name = kv.first; if (name.size() > 4 and name[0] == '{' and name[1] == '{' and name[name.size() - 2] == '}' and name[name.size() - 1] == '}') @@ -3426,22 +3432,22 @@ template struct drt_node { V v_; std::unordered_map children_; - std::vector> children_shared_pointers_; + drt_node_pool& pool_; }; -} // namespace internal -template struct dynamic_routing_table { +template struct dynamic_routing_table_impl { + dynamic_routing_table_impl() : root(pool) {} // Find a route and return reference to a procedure. auto& operator[](const std::string_view& r) { - strings.push_back(std::make_shared(r)); - std::string_view r2(*strings.back()); + auto [itr, is_inserted] = strings.emplace(std::string(r)); + std::string_view r2(*itr); return root.find_or_create(r2, 0); } - auto& operator[](const std::string& r) { - strings.push_back(std::make_shared(r)); - std::string_view r2(*strings.back()); - return root.find_or_create(r2, 0); + auto& operator[](const std::string& s) { + auto [itr, is_inserted] = strings.emplace(s); + std::string_view r(*itr); + return root.find_or_create(r, 0); } // Find a route and return an iterator. @@ -3450,8 +3456,36 @@ template struct dynamic_routing_table { template void for_all_routes(F f) const { root.for_all_routes(f); } auto end() const { return root.end(); } - std::vector> strings; - internal::drt_node root; + std::unordered_set strings; + drt_node_pool> pool; + drt_node root; +}; +} // namespace internal + +template struct dynamic_routing_table { + dynamic_routing_table() : impl_(std::make_shared>()) {} + dynamic_routing_table(const dynamic_routing_table& other) : impl_(other.impl_) {} + + // Assignment operator + dynamic_routing_table& operator=(const dynamic_routing_table& other) { + if (this != &other) { + impl_ = other.impl_; + } + return *this; + } + + // Find a route and return reference to a procedure. + auto& operator[](const std::string_view& r) { return impl_->operator[](r); } + auto& operator[](const std::string& s) { return impl_->operator[](s); } + + // Find a route and return an iterator. + auto find(const std::string_view& r) const { return impl_->find(r); } + + template void for_all_routes(F f) const { impl_->for_all_routes(f); } + auto end() const { return impl_->end(); } + + private: + std::shared_ptr> impl_; }; } // namespace li diff --git a/single_headers/lithium_mysql.hh b/single_headers/lithium_mysql.hh index 35f7fce..8e8b6b0 100644 --- a/single_headers/lithium_mysql.hh +++ b/single_headers/lithium_mysql.hh @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/single_headers/lithium_pgsql.hh b/single_headers/lithium_pgsql.hh index 0811052..30d3391 100644 --- a/single_headers/lithium_pgsql.hh +++ b/single_headers/lithium_pgsql.hh @@ -14,6 +14,7 @@ #include #include #include +#include #include #if __APPLE__ #include