From 081bd9041b55feaed555a20510ccfc5e57ecb0528c900db21dede820325685c6 Mon Sep 17 00:00:00 2001 From: paulhorn Date: Sat, 20 Jun 2026 20:46:49 +0200 Subject: [PATCH] feat: add slotted page skeleton with TDD cycle for page_create format: storage.h --- CMakeLists.txt | 8 +++- include/pauldb/storage.h | 94 ++++++++++++++++++++++++++++++++++------ src/storage/page.c | 78 ++++++++++++++++++++++++++++++++- test/storage/test_page.c | 34 +++++++++++++++ 4 files changed, 199 insertions(+), 15 deletions(-) create mode 100644 test/storage/test_page.c diff --git a/CMakeLists.txt b/CMakeLists.txt index a816279..1c53e60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,13 @@ target_include_directories(pauldb # Tests (CTest) # --------------------------------------------------------------------------- enable_testing() -# add_subdirectory(test) # einkommentieren sobald erste Tests da sind + +add_executable(test_page + test/storage/test_page.c + src/storage/page.c +) +target_include_directories(test_page PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) +add_test(NAME test_page COMMAND test_page) # --------------------------------------------------------------------------- # Installationsregeln (fur package() in conanfile.py) diff --git a/include/pauldb/storage.h b/include/pauldb/storage.h index 9afe9cf..be9870e 100644 --- a/include/pauldb/storage.h +++ b/include/pauldb/storage.h @@ -6,42 +6,110 @@ #include #ifdef __cplusplus -extern "C" { +extern "C" +{ + + #endif /* --- Page Management --- */ typedef struct Page Page; -Page *page_create(uint32_t page_id); +Page * +page_create +( + uint32_t page_id +); -int page_insert(Page *p, const void *data, size_t len); +int +page_insert +( + Page *p, + const void *data, + size_t len +); -void *page_get(Page *p, uint16_t slot_id, size_t *out_len); +void * +page_get +( + Page *p, + uint16_t slot_id, + size_t *out_len +); -void page_free(Page *p); +void +page_free +( + Page *p +); /* --- Heap (Multi-Page Row Store / Delta) --- */ typedef struct Heap Heap; -Heap *heap_create(void); +Heap * +heap_create +( + void +); -int heap_insert(Heap *h, const void *data, size_t len); +int +heap_insert +( + Heap *h, + const void *data, + size_t len +); -void heap_full_scan(Heap *h, void (*callback)(const void *, size_t)); +void +heap_full_scan +( + Heap *h, + void (*callback) + ( + const void *, + size_t + ) +); -void heap_free(Heap *h); +void +heap_free +( + Heap *h +); /* --- B+Tree Index --- */ typedef struct BTree BTree; -BTree *btree_create(void); +BTree * +btree_create +( + void +); -int btree_insert(BTree *bt, int64_t key, uint32_t page_id, uint16_t slot_id); +int +btree_insert +( + BTree *bt, + int64_t key, + uint32_t page_id, + uint16_t slot_id +); -int btree_lookup(BTree *bt, int64_t key, uint32_t *out_page, uint16_t *out_slot); +int +btree_lookup +( + BTree *bt, + int64_t key, + uint32_t *out_page, + uint16_t *out_slot +); -void btree_free(BTree *bt); +void +btree_free +( + BTree *bt +); #ifdef __cplusplus } diff --git a/src/storage/page.c b/src/storage/page.c index 2339b01..6cbf9a0 100644 --- a/src/storage/page.c +++ b/src/storage/page.c @@ -1,2 +1,78 @@ -/* page.c - Storage Engine (C) */ +/* src/storage/page.c + * Slotted Page - Storage Engine (C) + * + * Layout (4 KiB): + * + * Byte 0 Byte 4095 + * +----------+--------+--------+--- ---+------+------+ + * | Header | Slot 0 | Slot 1 | free |Tuple1|Tuple0| + * +----------+--------+--------+--- ---+------+------+ + * slots --> <-- tuples + * + * Header : page_id, num_slots, free_space_offset + * Slot : (offset, length) - wo im raw-Array liegt das Tuple? + * free_space_offset: naechste Schreibposition fuer Tuple-Daten + * startet bei PAGE_SIZE, nimmt ab + */ #include "pauldb/storage.h" + +#include +#include +#include + +#define PAGE_SIZE 4096 + +/* ---- interne Typen (nur in dieser Datei sichtbar) ---- */ + +typedef struct { + uint32_t page_id; + uint16_t num_slots; + uint16_t free_space_offset; +} PageHeader; + +typedef struct { + uint16_t offset; + uint16_t length; +} Slot; + +/* oeffentliche Page-Struktur (opak nach aussen) */ +struct Page { + uint8_t raw[PAGE_SIZE]; +}; + +/* ---- Hilfsfunktionen ---- */ + +static PageHeader *header(Page *p) { + return (PageHeader *)p->raw; +} + +/* ---- API ---- */ + +Page *page_create(uint32_t page_id) { + Page *p = malloc(sizeof(Page)); + if (!p) return NULL; + + memset(p->raw, 0, PAGE_SIZE); + + PageHeader *h = header(p); + h->page_id = page_id; + h->num_slots = 0; + h->free_space_offset = PAGE_SIZE; + + return p; +} + +void page_free(Page *p) { + free(p); +} + +/* page_insert und page_get folgen im naechsten TDD-Zyklus */ +int page_insert(Page *p, const void *data, size_t len) { + (void)p; (void)data; (void)len; + return -1; /* noch nicht implementiert */ +} + +void *page_get(Page *p, uint16_t slot_id, size_t *out_len) { + (void)p; (void)slot_id; (void)out_len; + return NULL; /* noch nicht implementiert */ +} diff --git a/test/storage/test_page.c b/test/storage/test_page.c new file mode 100644 index 0000000..67bb127 --- /dev/null +++ b/test/storage/test_page.c @@ -0,0 +1,34 @@ +/* test/storage/test_page.c + * + * TDD-Zyklus: test_page_create + * RED -> diese Datei schreiben, noch kein page.c -> Linker-Fehler + * GREEN -> page_create() + page_free() in page.c implementieren + */ +#include +#include + +#include "pauldb/storage.h" + +static void +test_create_returns_non_null +( + void +) +{ + Page *p = page_create(42); + assert(p != NULL); + page_free(p); + printf(" OK: page_create(42) returns non-NULL\n"); +} + +int +main +( + void +) +{ + printf("=== test_page ===\n"); + test_create_returns_non_null(); + printf("All tests passed.\n"); + return 0; +}