gradido/login_server/src/cpp/SingletonManager/SingletonTaskObserver.cpp
Ulf Gebhardt ac99a7097e Add 'login_server/' from commit 'ca71af1817a801db9a108c205bc298250d498c4b'
git-subtree-dir: login_server
git-subtree-mainline: 09ebb40de21084bb10ee466429d900a5e757d349
git-subtree-split: ca71af1817a801db9a108c205bc298250d498c4b
2021-03-17 22:05:25 +01:00

255 lines
6.8 KiB
C++

#include "SingletonTaskObserver.h"
#include "ErrorManager.h"
#include <cstring>
// ********************** Entry Structure *********************************
SingletonTaskObserver::UserObserverEntry::UserObserverEntry(const std::string& email, DHASH id)
: mEmail(email), mHash(id) {
memset(mTasksCount, 0, TASK_OBSERVER_COUNT * sizeof(int));
}
// ************************************************************************
SingletonTaskObserver::SingletonTaskObserver()
{
}
SingletonTaskObserver::~SingletonTaskObserver()
{
}
SingletonTaskObserver* SingletonTaskObserver::getInstance()
{
static SingletonTaskObserver one;
return &one;
}
void SingletonTaskObserver::addTask(const std::string& email, TaskObserverType type)
{
DHASH id = makeHash(email);
static const char* funcName = "SingletonTaskObserver::addTask_email";
auto em = ErrorManager::getInstance();
lock(funcName);
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
if (!entry) {
entry = new UserObserverEntry(email, id);
mObserverEntrys.addByHash(id, entry);
}
if (entry->mEmail != "" && entry->mEmail != email) {
em->addError(new ParamError(funcName, "hash collision with ", email.data()));
em->addError(new ParamError(funcName, "and ", entry->mEmail.data()));
em->sendErrorsAsEmail();
}
if (entry->mEmail == "") {
entry->mEmail = email;
}
entry->mTasksCount[type]++;
unlock();
}
void SingletonTaskObserver::addTask(DHASH id, TaskObserverType type)
{
static const char* funcName = "SingletonTaskObserver::addTask_id";
auto em = ErrorManager::getInstance();
lock(funcName);
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
if (!entry) {
entry = new UserObserverEntry("", id);
mObserverEntrys.addByHash(id, entry);
}
entry->mTasksCount[type]++;
unlock();
}
void SingletonTaskObserver::removeTask(const std::string& email, TaskObserverType type)
{
DHASH id = makeHash(email);
static const char* funcName = "SingletonTaskObserver::removeTask_email";
auto em = ErrorManager::getInstance();
lock(funcName);
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
if (entry) {
if (entry->mTasksCount[type] > 0) {
entry->mTasksCount[type]--;
}
else {
em->addError(new ParamError(funcName, "error more calls of removeTasks as addTasks", type));
em->sendErrorsAsEmail();
}
bool oneIsNotZero = false;
for (int i = 0; i < TASK_OBSERVER_COUNT; i++) {
if (entry->mTasksCount[type] != 0) {
oneIsNotZero = true;
continue;
}
}
if (!oneIsNotZero) {
mObserverEntrys.removeByHash(id);
delete entry;
}
}
else {
em->addError(new Error(funcName, "entry not found"));
em->sendErrorsAsEmail();
}
unlock();
}
void SingletonTaskObserver::removeTask(DHASH id, TaskObserverType type)
{
static const char* funcName = "SingletonTaskObserver::removeTask_id";
auto em = ErrorManager::getInstance();
lock(funcName);
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
if (entry) {
if (entry->mTasksCount[type] > 0) {
entry->mTasksCount[type]--;
}
else {
em->addError(new ParamError(funcName, "error more calls of removeTasks as addTasks", type));
em->sendErrorsAsEmail();
}
bool oneIsNotZero = false;
for (int i = 0; i < TASK_OBSERVER_COUNT; i++) {
if (entry->mTasksCount[type] != 0) {
oneIsNotZero = true;
continue;
}
}
if (!oneIsNotZero) {
mObserverEntrys.removeByHash(id);
delete entry;
}
}
else {
if (mObserverEntrys.getNItems() > 0) {
em->addError(new Error(funcName, "entry not found"));
em->addError(new ParamError(funcName, "existing entry count", mObserverEntrys.getNItems()));
em->sendErrorsAsEmail();
}
}
unlock();
}
bool SingletonTaskObserver::removeTasksCount(const std::string& email)
{
DHASH id = makeHash(email);
static const char* funcName = "SingletonTaskObserver::removeTasksCount";
auto em = ErrorManager::getInstance();
lock(funcName);
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
if (entry) {
mObserverEntrys.removeByHash(id);
unlock();
delete entry;
return true;
}
else {
unlock();
return false;
}
}
int SingletonTaskObserver::getTaskCount(const std::string& email, TaskObserverType type)
{
DHASH id = makeHash(email);
lock("SingletonTaskObserver::getTaskCount");
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
if (!entry || (entry->mEmail != "" && entry->mEmail != email)) {
unlock();
return -1;
}
int count = entry->mTasksCount[type];
unlock();
return count;
}
int SingletonTaskObserver::getTaskCount(DHASH id, TaskObserverType type)
{
lock("SingletonTaskObserver::getTaskCount");
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
if (!entry) {
unlock();
return -1;
}
int count = entry->mTasksCount[type];
unlock();
return count;
}
std::vector<int> SingletonTaskObserver::getTasksCount(const std::string& email)
{
DHASH id = makeHash(email);
lock("SingletonTaskObserver::getTasksCount");
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByHash(id));
std::vector<int> taskCounts;
if (!entry || entry->mEmail != email) {
unlock();
return taskCounts;
}
taskCounts.reserve(TASK_OBSERVER_COUNT);
for (int i = 0; i < TASK_OBSERVER_COUNT; i++) {
taskCounts.push_back(entry->mTasksCount[i]);
}
unlock();
return taskCounts;
}
int SingletonTaskObserver::getTasksCount(TaskObserverType type)
{
int type_sum_count = 0;
lock("SingletonTaskObserver::getTasksCount");
for (int i = 0; i < mObserverEntrys.getNItems(); i++) {
UserObserverEntry* entry = static_cast<UserObserverEntry*>(mObserverEntrys.findByIndex(i));
type_sum_count += entry->mTasksCount[type];
}
unlock();
return type_sum_count;
}
const char* SingletonTaskObserver::TaskObserverTypeToString(TaskObserverType type)
{
switch (type) {
case TASK_OBSERVER_PASSWORD_CREATION: return "password creation";
case TASK_OBSERVER_SIGN_TRANSACTION: return "sign transaction";
case TASK_OBSERVER_PREPARE_TRANSACTION: return "prepare transaction";
case TASK_OBSERVER_READY_FOR_SIGN_TRANSACTION: return "ready for sign transaction";
case TASK_OBSERVER_COUNT: return "COUNT";
case TASK_OBSERVER_INVALID: return "INVALID";
default: return "UNKNOWN";
}
}
TaskObserverType SingletonTaskObserver::StringToTaskObserverType(const std::string& typeString)
{
if ("password creation" == typeString) {
return TASK_OBSERVER_PASSWORD_CREATION;
}
else if ("sign transaction" == typeString) {
return TASK_OBSERVER_SIGN_TRANSACTION;
}
else if ("prepare transaction" == typeString) {
return TASK_OBSERVER_PREPARE_TRANSACTION;
}
else if ("ready for sign transaction" == typeString) {
return TASK_OBSERVER_READY_FOR_SIGN_TRANSACTION;
}
return TASK_OBSERVER_INVALID;
}