#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace reactor { // NonCopyable base class class NonCopyable { protected: NonCopyable() = default; ~NonCopyable() = default; NonCopyable(const NonCopyable&) = delete; NonCopyable& operator=(const NonCopyable&) = delete; NonCopyable(NonCopyable&&) noexcept = default; NonCopyable& operator=(NonCopyable&&) noexcept = default; }; // Network byte order utilities inline uint64_t hton64(uint64_t n) { static const int one = 1; static const char sig = *(char*)&one; if (sig == 0) return n; char* ptr = reinterpret_cast(&n); std::reverse(ptr, ptr + sizeof(uint64_t)); return n; } inline uint64_t ntoh64(uint64_t n) { return hton64(n); } // Lock-free MPSC queue template class LockFreeQueue : public NonCopyable { private: struct Node { Node() = default; Node(const T& data) : data_(std::make_unique(data)) {} Node(T&& data) : data_(std::make_unique(std::move(data))) {} std::unique_ptr data_; std::atomic next_{nullptr}; }; std::atomic head_; std::atomic tail_; public: LockFreeQueue() : head_(new Node), tail_(head_.load()) {} ~LockFreeQueue() { T output; while (dequeue(output)) {} delete head_.load(); } void enqueue(T&& input) { Node* node = new Node(std::move(input)); Node* prevhead = head_.exchange(node, std::memory_order_acq_rel); prevhead->next_.store(node, std::memory_order_release); } void enqueue(const T& input) { Node* node = new Node(input); Node* prevhead = head_.exchange(node, std::memory_order_acq_rel); prevhead->next_.store(node, std::memory_order_release); } bool dequeue(T& output) { Node* tail = tail_.load(std::memory_order_relaxed); Node* next = tail->next_.load(std::memory_order_acquire); if (next == nullptr) return false; output = std::move(*next->data_); tail_.store(next, std::memory_order_release); delete tail; return true; } bool empty() { Node* tail = tail_.load(std::memory_order_relaxed); Node* next = tail->next_.load(std::memory_order_acquire); return next == nullptr; } }; // Object Pool template class ObjectPool : public NonCopyable, public std::enable_shared_from_this> { private: std::vector objects_; std::mutex mutex_; public: std::shared_ptr getObject() { static_assert(!std::is_pointer_v, "ObjectPool type cannot be pointer"); T* p = nullptr; { std::lock_guard lock(mutex_); if (!objects_.empty()) { p = objects_.back(); objects_.pop_back(); } } if (!p) p = new T; std::weak_ptr> weakPtr = this->shared_from_this(); return std::shared_ptr(p, [weakPtr](T* ptr) { auto self = weakPtr.lock(); if (self) { std::lock_guard lock(self->mutex_); self->objects_.push_back(ptr); } else { delete ptr; } }); } }; // Simple Logger enum class LogLevel { TRACE, DEBUG, INFO, WARN, ERROR, FATAL }; class Logger : public NonCopyable { private: static inline LogLevel level_ = LogLevel::INFO; static inline std::unique_ptr file_; static inline std::mutex mutex_; std::ostringstream stream_; LogLevel msgLevel_; static const char* levelString(LogLevel level) { switch (level) { case LogLevel::TRACE: return "TRACE"; case LogLevel::DEBUG: return "DEBUG"; case LogLevel::INFO: return "INFO "; case LogLevel::WARN: return "WARN "; case LogLevel::ERROR: return "ERROR"; case LogLevel::FATAL: return "FATAL"; } return "UNKNOWN"; } static std::string timestamp() { auto now = std::chrono::system_clock::now(); auto time_t = std::chrono::system_clock::to_time_t(now); auto ms = std::chrono::duration_cast( now.time_since_epoch()) % 1000; char buf[64]; std::strftime(buf, sizeof(buf), "%Y%m%d %H:%M:%S", std::localtime(&time_t)); return std::string(buf) + "." + std::to_string(ms.count()); } public: Logger(LogLevel level) : msgLevel_(level) { if (level >= level_) { stream_ << timestamp() << " " << levelString(level) << " "; } } ~Logger() { if (msgLevel_ >= level_) { stream_ << "\n"; std::lock_guard lock(mutex_); if (file_ && file_->is_open()) { *file_ << stream_.str(); file_->flush(); } else { std::cout << stream_.str(); } } } template Logger& operator<<(const T& value) { if (msgLevel_ >= level_) { stream_ << value; } return *this; } static void setLevel(LogLevel level) { level_ = level; } static void setLogFile(const std::string& filename) { std::lock_guard lock(mutex_); file_ = std::make_unique(filename, std::ios::app); } }; // Task Queue interface class TaskQueue : public NonCopyable { public: virtual ~TaskQueue() = default; virtual void runTaskInQueue(const std::function& task) = 0; virtual void runTaskInQueue(std::function&& task) = 0; virtual std::string getName() const { return ""; } void syncTaskInQueue(const std::function& task) { std::promise promise; auto future = promise.get_future(); runTaskInQueue([&]() { task(); promise.set_value(); }); future.wait(); } }; // Concurrent Task Queue class ConcurrentTaskQueue : public TaskQueue { private: std::vector threads_; std::queue> taskQueue_; std::mutex taskMutex_; std::condition_variable taskCond_; std::atomic stop_{false}; std::string name_; void workerThread(int threadId) { while (!stop_) { std::function task; { std::unique_lock lock(taskMutex_); taskCond_.wait(lock, [this]() { return stop_ || !taskQueue_.empty(); }); if (taskQueue_.empty()) continue; task = std::move(taskQueue_.front()); taskQueue_.pop(); } task(); } } public: ConcurrentTaskQueue(size_t threadNum, const std::string& name = "ConcurrentTaskQueue") : name_(name) { for (size_t i = 0; i < threadNum; ++i) { threads_.emplace_back(&ConcurrentTaskQueue::workerThread, this, i); } } ~ConcurrentTaskQueue() { stop_ = true; taskCond_.notify_all(); for (auto& t : threads_) { if (t.joinable()) t.join(); } } void runTaskInQueue(const std::function& task) override { std::lock_guard lock(taskMutex_); taskQueue_.push(task); taskCond_.notify_one(); } void runTaskInQueue(std::function&& task) override { std::lock_guard lock(taskMutex_); taskQueue_.push(std::move(task)); taskCond_.notify_one(); } std::string getName() const override { return name_; } size_t getTaskCount() { std::lock_guard lock(taskMutex_); return taskQueue_.size(); } }; // Logging macros #define LOG_TRACE Logger(LogLevel::TRACE) #define LOG_DEBUG Logger(LogLevel::DEBUG) #define LOG_INFO Logger(LogLevel::INFO) #define LOG_WARN Logger(LogLevel::WARN) #define LOG_ERROR Logger(LogLevel::ERROR) #define LOG_FATAL Logger(LogLevel::FATAL) // Utility functions template void hashCombine(std::size_t& seed, const T& value) { std::hash hasher; seed ^= hasher(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } inline std::vector splitString(const std::string& s, const std::string& delimiter) { std::vector result; size_t start = 0; size_t end = s.find(delimiter); while (end != std::string::npos) { result.push_back(s.substr(start, end - start)); start = end + delimiter.length(); end = s.find(delimiter, start); } result.push_back(s.substr(start)); return result; } } // namespace reactor