From 35f1c63c80daa5740630e4f0fc2adc8b7ec5ebb4 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Sun, 11 Apr 2021 23:08:24 -0700 Subject: [PATCH] :racehorse: added add/del overhead in exchange for allusers scaling better --- include/bank.hpp | 62 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/include/bank.hpp b/include/bank.hpp index e2147a9..355ca69 100644 --- a/include/bank.hpp +++ b/include/bank.hpp @@ -18,23 +18,25 @@ private: users; /** - * @brief size_lock should be grabbed if the operation MODIFIES the size (unique) or READS from the users where size changes could distort (shared) + * @brief size_l should be grabbed if the operation MODIFIES the size (unique) or READS from the users where size changes could distort (shared) * */ - std::shared_mutex size_lock; + std::shared_mutex size_l; /** * @brief send_funds_l should be grabbed if balances are being MODIFIED (shared) or if an operation needs to READ without the intermediary states that sendfunds has (unique) * */ std::shared_mutex send_funds_l; + Json::Value temp_allusers; public: std::string admin_pass; bool AddUser(const std::string &name, std::string &&init_pass) { - std::unique_lock lock{size_lock}; + std::unique_lock lock{size_l}; + temp_allusers.insert(temp_allusers.size(), name); return users.try_emplace_l( name, [](User &) {}, std::move(init_pass)); } @@ -43,7 +45,8 @@ public: bool state = (admin_pass == attempt); if (state) { - std::unique_lock lock{size_lock}; + std::unique_lock lock{size_l}; + temp_allusers.insert(temp_allusers.size(), name); state = users.try_emplace_l( name, [](User &) {}, init_bal, std::move(init_pass)); } @@ -52,13 +55,39 @@ public: bool DelUser(const std::string &name, const std::string &attempt) { - std::unique_lock lock{size_lock}; - return users.erase_if(name, [&attempt](const User &u) { return (attempt == u.password); }); + std::unique_lock lock{size_l}; + bool state = false; + if (state = users.erase_if(name, [&attempt](const User &u) { return (attempt == u.password); })) + { + Json::Value temp; + for (Json::ArrayIndex i = 0; i < temp_allusers.size(); ++i) + { + if (temp_allusers[i] == name) + { + temp_allusers.removeIndex(i, &temp); + break; + } + } + } + return state; } bool AdminDelUser(const std::string &name, const std::string &attempt) { - std::unique_lock lock{size_lock}; - return users.erase_if(name, [this, &attempt](const User &) { return (admin_pass == attempt); }); + std::unique_lock lock{size_l}; + bool state = false; + if (state = users.erase_if(name, [this, &attempt](const User &) { return (admin_pass == attempt); })) + { + Json::Value temp; + for (Json::ArrayIndex i = 0; i < temp_allusers.size(); ++i) + { + if (temp_allusers[i] == name) + { + temp_allusers.removeIndex(i, &temp); + break; + } + } + } + return state; } bool SendFunds(const std::string &a_name, const std::string &b_name, uint_fast32_t amount, const std::string &attempt) @@ -144,15 +173,8 @@ public: Json::Value AllUsers() { - Json::Value temp; - Json::UInt i = 0; - std::shared_lock lock{size_lock}; //gives readers of users the lock - for (const auto &u : users) - { - //we know it contains this key but we call this func to grab mutex - temp[i++] = u.first; - } - return temp; + std::shared_lock lock{size_l}; //gives readers of users the lock + return temp_allusers; } void Save() @@ -165,7 +187,7 @@ public: //loading info into json temp { - std::shared_lock lock{size_lock}; //gives readers of users the lock + std::shared_lock lock{size_l}; //gives readers of users the lock std::unique_lock halt_funds{send_funds_l}; //halts all send fund requests for (const auto &u : users) { @@ -180,7 +202,6 @@ public: user_save.close(); } - //NOT THREAD SAFE, BY NO MEANS SHOULD THIS BE CALLED WHILE RECEIEVING REQUESTS void Load() { Json::CharReaderBuilder builder; @@ -196,8 +217,11 @@ public: else { user_save.close(); + Json::ArrayIndex i = 0; + std::unique_lock lock{size_l}; for (const auto &u : temp.getMemberNames()) { + temp_allusers[i++] = u; users.try_emplace(u, temp[u]["balance"].asUInt(), std::move(temp[u]["password"].asString())); } }