From 4af5e0423e3fe2a1f129727fb8a260f1baf4e18b Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Sat, 23 Aug 2025 06:10:55 -0400 Subject: [PATCH] Always use struct --- src/arena_allocator.hpp | 2 +- src/commit_request.hpp | 2 +- src/commit_request_parser.hpp | 2 +- src/config.hpp | 2 +- src/connection.cpp | 4 +++- src/connection.hpp | 9 +++++---- src/connection_handler.hpp | 2 +- src/connection_registry.hpp | 2 +- src/http_handler.hpp | 25 +++++++++++++------------ src/json_commit_request_parser.hpp | 2 +- src/json_tokens.hpp | 2 +- src/server.cpp | 6 ++++-- src/server.hpp | 10 +++++----- style.md | 27 ++++++++++++++++++--------- 14 files changed, 56 insertions(+), 41 deletions(-) diff --git a/src/arena_allocator.hpp b/src/arena_allocator.hpp index d5828d1..2c1eb5f 100644 --- a/src/arena_allocator.hpp +++ b/src/arena_allocator.hpp @@ -83,7 +83,7 @@ * @warning Do not share ArenaAllocator instances between threads. Use separate * instances per thread or per logical unit of work. */ -class ArenaAllocator { +struct ArenaAllocator { private: /** * @brief Internal block structure for the intrusive linked list. diff --git a/src/commit_request.hpp b/src/commit_request.hpp index 72481db..41eacea 100644 --- a/src/commit_request.hpp +++ b/src/commit_request.hpp @@ -60,7 +60,7 @@ struct Operation { * memory management and ownership. This class has no knowledge of any * specific serialization formats or encoding schemes. */ -class CommitRequest { +struct CommitRequest { private: ArenaAllocator arena_; std::optional request_id_; diff --git a/src/commit_request_parser.hpp b/src/commit_request_parser.hpp index d97ecbe..c0d36f9 100644 --- a/src/commit_request_parser.hpp +++ b/src/commit_request_parser.hpp @@ -13,7 +13,7 @@ * and streaming parsing (for incremental data processing). This allows * efficient handling of network protocols where data may arrive in chunks. */ -class CommitRequestParser { +struct CommitRequestParser { public: /** * @brief Status returned by streaming parse operations. diff --git a/src/config.hpp b/src/config.hpp index 3c23080..5a71946 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -83,7 +83,7 @@ struct Config { * auto config2 = ConfigParser::parse_toml_string(toml); * ``` */ -class ConfigParser { +struct ConfigParser { public: /** * @brief Load configuration from a TOML file. diff --git a/src/connection.cpp b/src/connection.cpp index e1568f0..265f91b 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -1,11 +1,13 @@ #include "connection.hpp" -#include "server.hpp" // Need this for releaseBackToServer implementation + #include #include #include #include #include +#include "server.hpp" // Need this for releaseBackToServer implementation + // Static thread-local storage for iovec buffer static thread_local std::vector g_iovec_buffer{IOV_MAX}; diff --git a/src/connection.hpp b/src/connection.hpp index 471f591..19846a8 100644 --- a/src/connection.hpp +++ b/src/connection.hpp @@ -1,7 +1,5 @@ #pragma once -#include "arena_allocator.hpp" -#include "connection_handler.hpp" #include #include #include @@ -10,6 +8,9 @@ #include #include +#include "arena_allocator.hpp" +#include "connection_handler.hpp" + #ifndef __has_feature #define __has_feature(x) 0 #endif @@ -39,7 +40,7 @@ * private. */ // Forward declaration -class Server; +struct Server; struct Connection { // No public constructor or factory method - only Server can create @@ -305,7 +306,7 @@ struct Connection { private: // Server is a friend and can access all networking internals - friend class Server; + friend struct Server; /** * @brief Private constructor - only accessible by Server. diff --git a/src/connection_handler.hpp b/src/connection_handler.hpp index d05622f..4799e60 100644 --- a/src/connection_handler.hpp +++ b/src/connection_handler.hpp @@ -17,7 +17,7 @@ struct Connection; * The networking layer manages connection lifecycle, I/O multiplexing, * and efficient data transfer, while handlers focus purely on protocol logic. */ -class ConnectionHandler { +struct ConnectionHandler { public: virtual ~ConnectionHandler() = default; diff --git a/src/connection_registry.hpp b/src/connection_registry.hpp index f793435..12f6c6f 100644 --- a/src/connection_registry.hpp +++ b/src/connection_registry.hpp @@ -16,7 +16,7 @@ struct Connection; * allocated on-demand as connections are created. * */ -class ConnectionRegistry { +struct ConnectionRegistry { public: /** * Initialize the connection registry. diff --git a/src/http_handler.hpp b/src/http_handler.hpp index 67bb475..be3b4b6 100644 --- a/src/http_handler.hpp +++ b/src/http_handler.hpp @@ -1,14 +1,16 @@ #pragma once +#include +#include +#include + +#include + #include "connection.hpp" #include "connection_handler.hpp" #include "perfetto_categories.hpp" #include "server.hpp" #include "thread_pipeline.hpp" -#include -#include -#include -#include /** * HTTP routes supported by WeaselDB server. @@ -60,14 +62,7 @@ struct HttpConnectionState { * HTTP/1.1 server implementation using llhttp for parsing. * Supports the WeaselDB REST API endpoints with enum-based routing. */ -class HttpHandler : public ConnectionHandler { - static constexpr int kFinalStageThreads = 2; - static constexpr int kLogSize = 12; - ThreadPipeline> pipeline{kLogSize, - {kFinalStageThreads}}; - std::vector finalStageThreads; - -public: +struct HttpHandler : ConnectionHandler { HttpHandler() { for (int threadId = 0; threadId < kFinalStageThreads; ++threadId) { finalStageThreads.emplace_back([this, threadId]() { @@ -124,6 +119,12 @@ public: static int onMessageComplete(llhttp_t *parser); private: + static constexpr int kFinalStageThreads = 2; + static constexpr int kLogSize = 12; + ThreadPipeline> pipeline{kLogSize, + {kFinalStageThreads}}; + std::vector finalStageThreads; + // Route handlers void handleGetVersion(Connection &conn, const HttpConnectionState &state); void handlePostCommit(Connection &conn, const HttpConnectionState &state); diff --git a/src/json_commit_request_parser.hpp b/src/json_commit_request_parser.hpp index e660360..96e4218 100644 --- a/src/json_commit_request_parser.hpp +++ b/src/json_commit_request_parser.hpp @@ -12,7 +12,7 @@ * This parser uses the weaseljson library to parse JSON-formatted * commit requests into CommitRequest objects. */ -class JsonCommitRequestParser : public CommitRequestParser { +struct JsonCommitRequestParser : CommitRequestParser { public: // Parser state enum class ParseState { diff --git a/src/json_tokens.hpp b/src/json_tokens.hpp index 2a2752d..a1fdb33 100644 --- a/src/json_tokens.hpp +++ b/src/json_tokens.hpp @@ -33,7 +33,7 @@ struct JsonToken { * } * ``` */ -class PerfectHash { +struct PerfectHash { public: /** * @brief Look up a JSON token by name using perfect hash. diff --git a/src/server.cpp b/src/server.cpp index 5c6e0c7..1da047b 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,6 +1,5 @@ #include "server.hpp" -#include "connection.hpp" -#include "connection_registry.hpp" + #include #include #include @@ -17,6 +16,9 @@ #include #include +#include "connection.hpp" +#include "connection_registry.hpp" + // Static thread-local storage for read buffer (used across different functions) static thread_local std::vector g_read_buffer; diff --git a/src/server.hpp b/src/server.hpp index 33afae7..62a2164 100644 --- a/src/server.hpp +++ b/src/server.hpp @@ -1,14 +1,15 @@ #pragma once -#include "config.hpp" -#include "connection_handler.hpp" -#include "connection_registry.hpp" #include #include #include #include #include +#include "config.hpp" +#include "connection_handler.hpp" +#include "connection_registry.hpp" + /** * High-performance multi-threaded server for handling network connections. * @@ -32,8 +33,7 @@ * - Prevention of accidental stack allocation that would break safety * guarantees */ -class Server : public std::enable_shared_from_this { -public: +struct Server : std::enable_shared_from_this { /** * Factory method to create a Server instance. * diff --git a/style.md b/style.md index fc95fbe..2e6c7cf 100644 --- a/style.md +++ b/style.md @@ -72,13 +72,22 @@ void add_block(size_t size); uint32_t initial_block_size_; ``` -### Classes and Structs -- **PascalCase** for class and struct names -- **Prefer struct over class** - public members at the top, avoid `class { public:` pattern +### Structs +- **PascalCase** for struct names +- **Always use struct** - eliminates debates about complexity and maintains consistency +- **Public members first, private after** - leverages struct's default public access +- Use `private:` sections when encapsulation is needed ```cpp -struct ArenaAllocator {}; -struct CommitRequest {}; -struct JsonCommitRequestParser {}; +struct ArenaAllocator { + // Public interface first + explicit ArenaAllocator(size_t initial_size = 1024); + void* allocate_raw(size_t size); + +private: + // Private members after + uint32_t initial_block_size_; + Block* current_block_; +}; ``` ### Enums @@ -173,8 +182,8 @@ std::unique_ptr parser; ## Code Structure -### Class Design -- **Move-only semantics** for resource-owning classes +### Struct Design +- **Move-only semantics** for resource-owning structs - **Explicit constructors** to prevent implicit conversions - **Delete copy operations** when inappropriate ```cpp @@ -308,7 +317,7 @@ static_assert(std::is_trivially_destructible_v, "Arena requires trivially des ## Documentation ### Doxygen Style -- **/** for class and public method documentation +- **/** for struct and public method documentation - **@brief** for short descriptions - **@param** and **@return** for function parameters - **@note** for important implementation notes