diff --git a/include/bank.hpp b/include/bank.hpp new file mode 100644 index 0000000..699708b --- /dev/null +++ b/include/bank.hpp @@ -0,0 +1,63 @@ +#pragma once +#include "parallel-hashmap/parallel_hashmap/phmap.h" +#include "user.hpp" + +class +{ +private: + phmap::parallel_node_hash_map< + std::string, User, + phmap::priv::hash_default_hash, + phmap::priv::hash_default_eq, + phmap::priv::Allocator>, + 4UL, + std::mutex> + users; + +public: + std::string admin_pass; + + bool AddUser(const std::string &name, std::string &&init_pass) + { + return users.try_emplace_l( + name, []() {}, init_pass); + } + bool AdminAddUser(const std::string &attempt, std::string &&name, uint_fast64_t init_bal, std::string &&init_pass) + { + const bool state = (admin_pass == attempt); + if (state) + { + users.try_emplace_l( + name, []() {}, init_bal, init_pass); + } + return state; + } + bool SendFunds(const std::string &a_name, const std::string &b_name, uint_fast64_t amount, const std::string &attempt) + { + //if A exists, A can afford it, and A's password matches + bool state = false; + + users.modify_if(a_name, [&state, amount, &attempt](User &a) { + if (state = (a.balance >= amount) && (a.password == attempt)) + { + a.balance -= amount; + } + }); + + if (state) + { + //if B doesnt exist + if (!users.modify_if(b_name, [amount](User &b) { + b.balance += amount; + })) + { + //attempt to refund if destination doesnt exist + users.modify_if(a_name, [amount](User &a) { + a.balance += amount; + }); + } + } + + return state; + } +} Bank; \ No newline at end of file diff --git a/include/user.hpp b/include/user.hpp index 1594dbf..aeca485 100644 --- a/include/user.hpp +++ b/include/user.hpp @@ -2,17 +2,11 @@ #include #include -class User +struct User { -private: - uint_fast64_t balance; + uint_fast64_t balance = 0; std::string password; - //for read/write of object's state concurrently - std::mutex bal_lock; - std::mutex pass_lock; - -public: /** * @brief User constructor * @@ -28,64 +22,54 @@ public: */ User(uint_fast64_t init_bal, std::string &&init_pass) : balance(init_bal), password(init_pass) {} - bool ChangePassword(const std::string &attempt, std::string &&new_pass) - { - std::lock_guard lock{pass_lock}; - const bool state = (password == attempt); - if (state) - { - password = new_pass; - } - return state; - } + // bool ChangePassword(const std::string &attempt, std::string &&new_pass) + // { + // const bool state = (password == attempt); + // if (state) + // { + // password = new_pass; + // } + // return state; + // } - /** - * @brief SendFunds allows sending of money between users if verification is provided in the form of a password and if the user has sufficient funds - * - * @param a first user - * @param b second user - * @param amount amount being sent - * @param attempt password of first user - * @return wether transaction was succesful - */ - static bool SendFunds(User &a, User &b, uint_fast64_t amount, const std::string &attempt) - { - bool state; - { - std::lock_guard lock{a.pass_lock}; - state = (a.password == attempt); - } + // // /** + // // * @brief SendFunds allows sending of money between users if verification is provided in the form of a password and if the user has sufficient funds + // // * + // // * @param a first user + // // * @param b second user + // // * @param amount amount being sent + // // * @param attempt password of first user + // // * @return wether transaction was succesful + // // */ + // // static bool SendFunds(User &a, User &b, uint_fast64_t amount, const std::string &attempt) + // // { + // // const bool state = (a.password == attempt) && (a.balance >= amount); + // // if (state) + // // { + // // a.balance -= amount; + // // b.balance += amount; + // // } + // // return state; + // // } - std::scoped_lock lock{a.bal_lock, b.bal_lock}; - state = state && (a.balance >= amount); - if (state) - { - a.balance -= amount; - b.balance += amount; - } - return state; - } + // /** + // * @brief Get the balance of the User object + // * + // * @return the balance + // */ + // uint_fast64_t GetBal() const + // { + // return balance; + // } - /** - * @brief Get the balance of the User object - * - * @return the balance - */ - uint_fast64_t GetBal() - { - std::lock_guard lock{bal_lock}; - return balance; - } - - /** - * @brief Used for Verification of password by external services, this can be used for logging in or signature - * - * @param attempt the password - * @return wether the passwords match - */ - bool VerifyPassword(const std::string &attempt) //for connected services - { - std::lock_guard lock{pass_lock}; - return (password == attempt); - } + // /** + // * @brief Used for Verification of password by external services, this can be used for logging in or signature + // * + // * @param attempt the password + // * @return wether the passwords match + // */ + // bool VerifyPassword(const std::string &attempt) const + // { + // return (password == attempt); + // } }; \ No newline at end of file