diff --git a/style.md b/style.md index b83315c..b1bc85d 100644 --- a/style.md +++ b/style.md @@ -26,7 +26,7 @@ This document describes the C++ coding style used in the WeaselDB project. These - **Always use std:: prefixed versions** of C library functions for consistency and clarity - **Use C++ style headers** (``, ``, etc.) instead of C style headers (``, ``, etc.) - This applies to all standard libc functions: `std::abort()`, `std::fprintf()`, `std::free()`, `std::memcpy()`, `std::strlen()`, `std::strncpy()`, `std::memset()`, `std::signal()`, etc. -- Exception: Functions with no std:: equivalent (e.g., `perror()`, `gai_strerror()`) and system-specific headers (e.g., ``, ``) +- **Exception:** Functions with no std:: equivalent (e.g., `perror()`, `gai_strerror()`) and system-specific headers (e.g., ``, ``) ```cpp // Preferred - C++ style #include @@ -89,7 +89,8 @@ auto ptr = static_cast(malloc(sizeof(int))); // Explicit conversion auto base = static_cast(derived_ptr); // Safe upcast auto derived = dynamic_cast(base_ptr); // Runtime type checking auto mutable_ptr = const_cast(const_ptr); // Remove const (rare) -auto addr = reinterpret_cast(ptr); // Low-level operations (very rare, delicate) +// reinterpret_cast can be appropriate for low-level operations (very rare) +auto addr = reinterpret_cast(ptr); // Pointer to integer conversion ``` ### Performance Focus @@ -99,7 +100,7 @@ auto addr = reinterpret_cast(ptr); // Low-level operations (v - **Strive for 0% CPU usage when idle** - avoid polling, busy waiting, or unnecessary background activity - Use **inline functions** for performance-critical code (e.g., `allocate_raw`) - **Zero-copy operations** with `std::string_view` over string copying -- **Arena allocation** for efficient memory management (see Memory Management section for details) +- **Arena allocation** for efficient memory management (~1ns vs ~20-270ns for malloc) ### Complexity Control - **Encapsulation is the main tool for controlling complexity** @@ -124,11 +125,11 @@ void add_block(int64_t size); int32_t initial_block_size_; ``` -### Structs -- **PascalCase** for struct names -- **Always use struct** - eliminates debates about complexity and maintains consistency +### Classes and Structs +- **PascalCase** for class/struct names +- **Always use struct keyword** - eliminates debates about complexity and maintains consistency - **Public members first, private after** - puts the interface users care about at the top, implementation details below -- **Full encapsulation still applies** - use `private:` sections to hide implementation details and maintain deep, capable classes +- **Full encapsulation still applies** - use `private:` sections to hide implementation details and maintain deep, capable structs - The struct keyword doesn't mean shallow design - it means interface-first organization for human readers ```cpp struct ArenaAllocator { @@ -220,8 +221,8 @@ std::unique_ptr parser; ## Code Structure -### Struct Design -- **Move-only semantics** for resource-owning structs +### Class Design +- **Move-only semantics** for resource-owning types - **Explicit constructors** to prevent implicit conversions - **Delete copy operations** when inappropriate ```cpp @@ -229,12 +230,12 @@ struct ArenaAllocator { explicit ArenaAllocator(int64_t initial_size = 1024); // Copy construction is not allowed - ArenaAllocator(const ArenaAllocator &) = delete; - ArenaAllocator &operator=(const ArenaAllocator &) = delete; + ArenaAllocator(const ArenaAllocator &source) = delete; + ArenaAllocator &operator=(const ArenaAllocator &source) = delete; // Move semantics - ArenaAllocator(ArenaAllocator &&other) noexcept; - ArenaAllocator &operator=(ArenaAllocator &&other) noexcept; + ArenaAllocator(ArenaAllocator &&source) noexcept; + ArenaAllocator &operator=(ArenaAllocator &&source) noexcept; private: int32_t initial_block_size_; @@ -251,9 +252,9 @@ private: - **noexcept specification** for move operations and non-throwing functions ```cpp std::span operations() const { return operations_; } -void process_data(std::string_view data); // ≤ 16 bytes, pass by value -void process_request(const CommitRequest& req); // > 16 bytes, pass by reference -ArenaAllocator(ArenaAllocator &&other) noexcept; +void process_data(std::string_view request_data); // ≤ 16 bytes, pass by value +void process_request(const CommitRequest& commit_request); // > 16 bytes, pass by reference +ArenaAllocator(ArenaAllocator &&source) noexcept; ``` ### Template Usage @@ -273,13 +274,15 @@ ArenaAllocator(ArenaAllocator &&other) noexcept; auto server = Server::create(config, handler); // Returns shared_ptr // Exclusive ownership - single owner, transfer via move -auto connection = Connection::createForServer(...); // Returns unique_ptr +auto connection = Connection::createForServer(addr, fd, connection_id, handler, server_ref); // Friend-based factory for access control struct Connection { - void appendMessage(std::string_view data); + void appendMessage(std::string_view message_data); private: - Connection(/* args */); // Private constructor + Connection(struct sockaddr_storage client_addr, int file_descriptor, + int64_t connection_id, ConnectionHandler* request_handler, + std::weak_ptr server_ref); friend struct Server; // Only Server can construct }; ``` @@ -302,15 +305,15 @@ for (auto &precondition : preconditions_) { ## Memory Management ### Ownership & Allocation -- **Arena allocators** for request-scoped memory with **STL allocator adapters** (provides ~1ns allocation vs ~20-270ns for malloc) +- **Arena allocators** for request-scoped memory with **STL allocator adapters** (see Performance Focus section for characteristics) - **String views** pointing to arena-allocated memory for zero-copy operations - **STL containers with arena allocators require default construction after arena reset** - `clear()` is not sufficient ```cpp // STL containers with arena allocators - correct reset pattern -std::vector> operations(arena_alloc); +std::vector> operations(arena_allocator); // ... use container ... operations = {}; // Default construct - clear() won't work correctly -arena.reset(); // Reset arena memory +arena_allocator.reset(); // Reset arena memory ``` ### Resource Management @@ -346,12 +349,12 @@ arena.reset(); // Reset arena memory enum class ParseResult { Success, InvalidJson, MissingField }; // System failure - abort immediately -void* memory = malloc(size); +void* memory = std::malloc(size); if (!memory) { std::fprintf(stderr, "ArenaAllocator: Memory allocation failed\n"); std::abort(); } -// ... use memory, eventually free it +// ... use memory, eventually std::free(memory) // Programming error - precondition violation (may be omitted for performance) assert(ptr != nullptr && "Precondition violated: pointer must be non-null"); @@ -396,9 +399,9 @@ do { } while (fd == -1 && errno == EINTR); if (fd == -1) { - // Handle other errors + // Handle other errors (perror has no std:: equivalent) perror("accept"); - abort(); + std::abort(); } ``` @@ -408,9 +411,9 @@ The `close()` system call is a special case on Linux. According to `man 2 close` ```cpp // Correct: Do not retry close() on EINTR -int e = close(fd); -if (e == -1 && errno != EINTR) { - // Handle non-EINTR errors only +int result = close(fd); +if (result == -1 && errno != EINTR) { + // Handle non-EINTR errors only (perror has no std:: equivalent) perror("close"); std::abort(); } @@ -444,14 +447,14 @@ When in doubt, consult the `man` page for the specific system call to see if it ```cpp /** * @brief Type-safe version of realloc_raw for arrays of type T. - * @param ptr Pointer to the existing allocation - * @param old_size Size in number of T objects - * @param new_size Desired new size in number of T objects + * @param existing_ptr Pointer to the existing allocation + * @param current_size Size in number of T objects + * @param requested_size Desired new size in number of T objects * @return Pointer to reallocated memory * @note Prints error to stderr and calls std::abort() if allocation fails */ template -T *realloc(T *ptr, int32_t old_size, int32_t new_size); +T *realloc(T *existing_ptr, int32_t current_size, int32_t requested_size); ``` ### Code Comments