Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Core/DB): port WarheadCore database #16659

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 37 additions & 25 deletions src/common/Threading/PCQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,37 @@ template <typename T>
class ProducerConsumerQueue
{
private:
std::mutex _queueLock;
mutable std::mutex _queueLock;
std::queue<T> _queue;
std::condition_variable _condition;
std::atomic<bool> _shutdown;
std::atomic<bool> _shutdown{ false };

public:
ProducerConsumerQueue() : _shutdown(false) { }
ProducerConsumerQueue() = default;

void Push(const T& value)
void Push(T const& value)
{
std::lock_guard<std::mutex> lock(_queueLock);
_queue.push(std::move(value));

_queue.push(value);
_condition.notify_one();
}

bool Empty()
void Push(T&& value)
{
std::lock_guard<std::mutex> lock(_queueLock);
_queue.push(std::move(value));
_condition.notify_one();
}

bool Empty() const
{
std::lock_guard<std::mutex> lock(_queueLock);
return _queue.empty();
}

[[nodiscard]] size_t Size() const
std::size_t Size() const
{
std::lock_guard<std::mutex> lock(_queueLock);
return _queue.size();
}

Expand All @@ -61,14 +67,10 @@ class ProducerConsumerQueue
std::lock_guard<std::mutex> lock(_queueLock);

if (_queue.empty() || _shutdown)
{
return false;
}

value = _queue.front();

value = std::move(_queue.front());
_queue.pop();

return true;
}

Expand All @@ -79,17 +81,28 @@ class ProducerConsumerQueue
// we could be using .wait(lock, predicate) overload here but it is broken
// https://connect.microsoft.com/VisualStudio/feedback/details/1098841
while (_queue.empty() && !_shutdown)
{
_condition.wait(lock);
}

if (_queue.empty() || _shutdown)
{
return;
}

value = _queue.front();
_queue.pop();
}

void WaitAndPop(T& value, std::atomic<bool> const& customCancel)
{
std::unique_lock<std::mutex> lock(_queueLock);

// we could be using .wait(lock, predicate) overload here but it is broken
// https://connect.microsoft.com/VisualStudio/feedback/details/1098841
while (_queue.empty() && !_shutdown && !customCancel)
_condition.wait(lock);

if (_queue.empty() || _shutdown || customCancel)
return;

value = _queue.front();
_queue.pop();
}

Expand All @@ -101,22 +114,21 @@ class ProducerConsumerQueue
{
T& value = _queue.front();

DeleteQueuedObject(value);
if constexpr (std::is_pointer_v<T>)
delete value;

_queue.pop();
}

_shutdown = true;

_condition.notify_all();
}

private:
template<typename E = T>
typename std::enable_if<std::is_pointer<E>::value>::type DeleteQueuedObject(E& obj) { delete obj; }

template<typename E = T>
typename std::enable_if<!std::is_pointer<E>::value>::type DeleteQueuedObject(E const& /*packet*/) { }
void NotifyAll()
{
std::lock_guard<std::mutex> lock(_queueLock);
_condition.notify_all();
}
};

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,42 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "MySQLThreading.h"
#include "MySQLWorkaround.h"
#include "FileUtil.h"
#include <algorithm>
#include <filesystem>

void MySQL::Library_Init()
{
mysql_library_init(-1, nullptr, nullptr);
}
namespace fs = std::filesystem;

void MySQL::Library_End()
void Acore::File::CorrectDirPath(std::string& path)
{
mysql_library_end();
if (path.empty())
{
path = fs::absolute(fs::current_path()).generic_string();
return;
}

std::replace(std::begin(path), std::end(path), '\\', '/');

if (path.at(path.length() - 1) != '/')
path.push_back('/');
}

uint32 MySQL::GetLibraryVersion()
bool Acore::File::CreateDirIfNeed(std::string_view path)
{
return MYSQL_VERSION_ID;
if (path.empty())
return true;

fs::path dirPath{ path };

if (fs::exists(dirPath) && fs::is_directory(path))
return true;

try
{
return fs::create_directory(dirPath);
}
catch (...)
{
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _MYSQLTHREADING_H
#define _MYSQLTHREADING_H
#ifndef AC_FILE_UTIL_H_
#define AC_FILE_UTIL_H_

#include "Define.h"
#include <string_view>

namespace MySQL
namespace Acore::File
{
AC_DATABASE_API void Library_Init();
AC_DATABASE_API void Library_End();
AC_DATABASE_API uint32 GetLibraryVersion();
AC_COMMON_API void CorrectDirPath(std::string& path);
AC_COMMON_API bool CreateDirIfNeed(std::string_view path);
}

#endif
62 changes: 62 additions & 0 deletions src/common/Utilities/StopWatch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef AC_STOP_WATCH_H_
#define AC_STOP_WATCH_H_

#include "Timer.h"
#include <fmt/core.h>

class StopWatch
{
using clock = std::chrono::steady_clock;

public:
explicit StopWatch(uint8 outCount = 3)
: _startTime{ clock::now() }, _outCount{ outCount } {}

[[nodiscard]] Microseconds Elapsed() const
{
return std::chrono::duration_cast<Microseconds>(clock::now() - _startTime);
}

void Reset()
{
_startTime = clock::now();
}

[[nodiscard]] uint8 GetOutCount() const
{
return _outCount;
}

private:
std::chrono::time_point<clock> _startTime;
uint8 _outCount;
};

template<>
struct fmt::formatter<StopWatch> : formatter<string_view>
{
template<typename FormatContext>
auto format(const StopWatch& sw, FormatContext& ctx) -> decltype(ctx.out())
{
return formatter<string_view>::format(Acore::Time::ToTimeString(sw.Elapsed(), sw.GetOutCount()), ctx);
}
};

#endif
21 changes: 20 additions & 1 deletion src/common/Utilities/StringFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include "Define.h"
#include <locale>

constexpr char CHAR_WHITESPACE = ' ';

template<class Str>
AC_COMMON_API Str Acore::String::Trim(const Str& s, const std::locale& loc /*= std::locale()*/)
{
Expand Down Expand Up @@ -50,6 +52,22 @@ AC_COMMON_API Str Acore::String::Trim(const Str& s, const std::locale& loc /*= s
return s;
}

std::string_view Acore::String::TrimLeft(std::string_view str)
{
while (!str.empty() && (str.front() == CHAR_WHITESPACE))
str.remove_prefix(1);

return str;
}

std::string_view Acore::String::TrimRight(std::string_view str)
{
while (!str.empty() && (str.back() == CHAR_WHITESPACE))
str.remove_suffix(1);

return str;
}

std::string Acore::String::TrimRightInPlace(std::string& str)
{
int pos = int(str.size()) - 1;
Expand All @@ -71,7 +89,8 @@ std::string Acore::String::TrimRightInPlace(std::string& str)
* @param suffix Character to add at the end of the str
* @return std::string Suffixed string
*/
std::string Acore::String::AddSuffixIfNotExists(std::string str, const char suffix) {
std::string Acore::String::AddSuffixIfNotExists(std::string& str, char suffix)
{
if (str.empty() || (str.at(str.length() - 1) != suffix))
str.push_back(suffix);

Expand Down
5 changes: 3 additions & 2 deletions src/common/Utilities/StringFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,10 @@ namespace Acore::String
template<class Str>
AC_COMMON_API Str Trim(const Str& s, const std::locale& loc = std::locale());

AC_COMMON_API std::string_view TrimLeft(std::string_view str);
AC_COMMON_API std::string_view TrimRight(std::string_view str);
AC_COMMON_API std::string TrimRightInPlace(std::string& str);

AC_COMMON_API std::string AddSuffixIfNotExists(std::string str, const char suffix);
AC_COMMON_API std::string AddSuffixIfNotExists(std::string& str, char suffix);
}

#endif
Loading
Loading