integrated logs into user struct

This commit is contained in:
EntireTwix 2021-04-22 00:11:13 -07:00
parent a3d93b5831
commit f75f519e64
6 changed files with 34 additions and 96 deletions

3
.gitignore vendored
View file

@ -1,3 +1,2 @@
.vscode .vscode
build build
config.json

View file

@ -4,13 +4,6 @@
"address": "0.0.0.0", "address": "0.0.0.0",
"port": 80, "port": 80,
"https": false "https": false
},
{
"address": "0.0.0.0",
"port": 443,
"https": true,
"cert": "",
"key": ""
} }
] ]
} }

View file

@ -4,7 +4,6 @@
#include "xxhash.h" #include "xxhash.h"
#include "parallel-hashmap/parallel_hashmap/phmap.h" #include "parallel-hashmap/parallel_hashmap/phmap.h"
#include "user.hpp" #include "user.hpp"
#include "log.hpp"
class class
{ {
@ -18,14 +17,6 @@ private:
std::mutex> std::mutex>
users; users;
phmap::parallel_flat_hash_map<
std::string, Log,
phmap::priv::hash_default_hash<std::string>,
phmap::priv::hash_default_eq<std::string>,
phmap::priv::Allocator<phmap::priv::Pair<const std::string, Log>>,
4UL,
std::mutex>
logs;
/** /**
* @brief size_l should be grabbed if the operation MODIFIES the size (shared), this is so that when save claims unique * @brief size_l should be grabbed if the operation MODIFIES the size (shared), this is so that when save claims unique
* *
@ -61,34 +52,17 @@ public:
bool DelUser(const std::string &name, const std::string &attempt) bool DelUser(const std::string &name, const std::string &attempt)
{ {
bool state; std::shared_lock<std::shared_mutex> lock{size_l};
{ return users.erase_if(name, [&attempt](User &u) { return (XXH3_64bits(attempt.data(), attempt.size()) == u.password); });
std::shared_lock<std::shared_mutex> lock{size_l};
state = users.erase_if(name, [&attempt](User &u) { return (XXH3_64bits(attempt.data(), attempt.size()) == u.password); });
}
if (state)
{
logs.erase(name);
}
return state;
} }
bool AdminDelUser(const std::string &name, const std::string &attempt) bool AdminDelUser(const std::string &name, const std::string &attempt)
{ {
bool state; std::shared_lock<std::shared_mutex> lock{size_l};
{ return users.erase_if(name, [this, &attempt](const User &) { return (admin_pass == attempt); });
std::shared_lock<std::shared_mutex> lock{size_l};
state = users.erase_if(name, [this, &attempt](const User &) { return (admin_pass == attempt); });
}
if (state)
{
logs.erase(name);
}
return state;
} }
bool SendFunds(const std::string &a_name, const std::string &b_name, uint_fast32_t amount, const std::string &attempt) bool SendFunds(const std::string &a_name, const std::string &b_name, uint_fast32_t amount, const std::string &attempt)
{ {
//cant send money to self, from self or amount is 0 //cant send money to self, from self or amount is 0
if (a_name == b_name || !amount) if (a_name == b_name || !amount)
{ {
@ -121,28 +95,14 @@ public:
} }
} }
} }
if (state) if (state)
{ {
//if user lacks a log, one is created, this is to reduce usage
Transaction temp(a_name, b_name, amount); Transaction temp(a_name, b_name, amount);
Transaction temp2 = temp; // to keep same time users.modify_if(a_name, [&temp](User &a) {
a.log.AddTrans(std::forward<Transaction>(temp));
users.if_contains(a_name, [this, &temp, &a_name](const User &u) {
if (logs.try_emplace_l(a_name, [&temp](Log &l) { l.AddTrans(std::move(temp)); }))
{
logs.modify_if(a_name, [&temp](Log &l) {
l.AddTrans(std::move(temp));
});
}
}); });
users.if_contains(a_name, [this, &temp2, &b_name](const User &u) { users.modify_if(b_name, [&temp](User &b) {
if (logs.try_emplace_l(b_name, [&temp2](Log &l) { l.AddTrans(std::move(temp2)); })) b.log.AddTrans(std::move(temp));
{
logs.modify_if(b_name, [&temp2](Log &l) {
l.AddTrans(std::move(temp2));
});
}
}); });
} }
@ -199,44 +159,26 @@ public:
Json::Value GetLogs(const std::string &name, const std::string &attempt) Json::Value GetLogs(const std::string &name, const std::string &attempt)
{ {
bool state = false; Json::Value res = -1;
users.if_contains(name, [&state, &attempt](const User &u) { users.if_contains(name, [&res](const User &u) {
state = XXH3_64bits(attempt.data(), attempt.size()) == u.password; uint32_t j;
}); for (uint32_t i = u.log.data.size() - 1; i > 0; --i)
if (!state)
{
return 0;
}
Json::Value res;
if (!(logs.if_contains(name, [&res](const Log &l) {
uint32_t j;
for (uint32_t i = l.data.size() - 1; i > 0; --i)
{
j = 24 - i;
if (!l.data[i].amount)
{
return;
}
res[j]["to"] = l.data[i].to;
res[j]["from"] = l.data[i].from;
res[j]["amount"] = l.data[i].amount;
res[j]["time"] = (Json::UInt)l.data[i].time;
}
})))
{
if (users.contains(name))
{ {
return 1; j = u.log.data.size() - 1 - i;
if (!u.log.data[i].amount)
{
return;
}
res[j]["to"] = u.log.data[i].to;
res[j]["from"] = u.log.data[i].from;
res[j]["amount"] = u.log.data[i].amount;
res[j]["time"] = (Json::UInt64)u.log.data[i].time;
} }
return -1; });
}
return res; return res;
} }
void void Save()
Save()
{ {
Json::StreamWriterBuilder builder; Json::StreamWriterBuilder builder;
const std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter()); const std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());

View file

@ -5,9 +5,13 @@
struct Log struct Log
{ {
std::array<Transaction, 25> data; std::vector<Transaction> data;
void AddTrans(Transaction &&v) void AddTrans(Transaction &&v)
{ {
if (!data.size())
{
data.resize(25);
}
std::rotate(data.begin(), data.begin() + 1, data.end()); std::rotate(data.begin(), data.begin() + 1, data.end());
data[24] = std::move(v); data[24] = std::move(v);
} }

View file

@ -8,7 +8,7 @@ struct Transaction
std::string from = "", to = ""; std::string from = "", to = "";
uint32_t amount = 0; uint32_t amount = 0;
uint32_t time = 0; uint64_t time = 0;
void Concatinate(std::string &s) void Concatinate(std::string &s)
{ {

View file

@ -1,12 +1,13 @@
#pragma once #pragma once
#include <json/json.h> #include <json/json.h>
#include <string> #include <string>
#include "log.hpp"
struct User struct User
{ {
uint_fast32_t balance = 0; uint_fast32_t balance = 0;
uint64_t password; uint64_t password;
bool is_admin = false; Log log;
/** /**
* @brief User constructor * @brief User constructor
@ -21,15 +22,14 @@ struct User
* @param init_bal initial balance * @param init_bal initial balance
* @param init_pass initial password * @param init_pass initial password
*/ */
User(uint_fast32_t init_bal, std::string &&init_pass, bool state = false) : balance(init_bal), password(XXH3_64bits(init_pass.data(), init_pass.size())), is_admin(state) {} User(uint_fast32_t init_bal, std::string &&init_pass, bool state = false) : balance(init_bal), password(XXH3_64bits(init_pass.data(), init_pass.size())) {}
User(uint_fast32_t init_bal, uint64_t init_pass, bool state = false) : balance(init_bal), password(init_pass), is_admin(state) {} User(uint_fast32_t init_bal, uint64_t init_pass, bool state = false) : balance(init_bal), password(init_pass) {}
Json::Value Serialize() const Json::Value Serialize() const
{ {
Json::Value res; Json::Value res;
res["balance"] = (Json::UInt)balance; res["balance"] = (Json::UInt)balance;
res["password"] = (Json::UInt64)password; res["password"] = (Json::UInt64)password;
res["is_admin"] = is_admin;
return res; return res;
} }
}; };