Skip to main content

File & Page Layout Changes

This page documents every new file added, every existing file modified, and any changes to on-disk page structures introduced in the update / delete / compaction phase.


Page Layout Changes

Table header page (Page 0) — dead_tuple_count field added

File affected: all .dat heap files

Previously, page 0 stored only page_count in bytes 0–4. This phase adds a second u32 field at bytes 4–8.

New layout:

Offset  Size  Field
────── ──── ───────────────────
0 4 B page_count (u32, little-endian)
4 4 B dead_tuple_count (u32, little-endian) ← NEW
8 … reserved / zeroed

dead_tuple_count is incremented atomically on every soft-delete (DELETE and the old-version step of UPDATE) and reset to 0 after a successful compaction. The autovacuum scheduler reads this field to compute each table's compaction priority.


New Files

Backend

FilePurpose
src/backend/executor/delete.rsFull DELETE implementation: WHERE parsing, slot flagging, dead-tuple accounting, VM update, logging
src/backend/executor/update.rsFull UPDATE implementation: scan matching tuples → soft-delete old version → reinsert new version
src/backend/executor/api.rsIntegration façade for the heap/FSM team — exposes insert_raw_tuple, rebuild_table_fsm, update_page_free_space
src/backend/page/page_lock.rsRAII page-level write lock using a global OnceLock<Mutex<PageLockRegistry>>
src/backend/log/operation_log.rsJSON-line operation logging for update, delete, and compaction
src/backend/visibility_map/vm.rsVisibility Map: per-page all-visible tracking used by autovacuum to skip clean pages
src/backend/instrumentation.rsLock-free atomic counters for FSM and Heap operation telemetry (required by heap team)
src/bin/benchmark_compare.rsBenchmark harness — RookDB vs PostgreSQL for UPDATE, DELETE, VACUUM, and VACUUM FULL

Tests

FileCoverage
code/tests/test_delete.rs57 tests: soft-delete correctness, zero-match deletes, delete-all, WHERE edge cases, page-lock safety
code/tests/test_update.rs30 tests: condition matching, arithmetic SET, zero-match updates, RETURNING, page-lock behaviour
code/tests/test_compaction.rs10 tests: live-tuple preservation, lock held during rewrite, idempotency, post-compaction free space
code/tests/test_page_lock.rsTiming tests: verifies a held PageWriteLock delays concurrent mutators by ≥ 4 500 ms
code/tests/test_fsm_large.rsFSM correctness at scale after many inserts and compactions

Intermediate / Generated Files

Logs are created at runtime per-database and per-table:

database/logs/
└── <db_name>/
└── <table_name>/
├── update.log
├── delete.log
└── compaction.log

Each file is append-only. One JSON object per line:

{
"timestamp": "2026-04-20T12:34:56.789Z",
"operation": "delete",
"details": { "deleted_count": 1000, "condition_groups": 1 },
"status": "success"
}

Modified Files

src/backend/table/table_file.rs

Added functions:

FunctionChange
read_dead_tuple_count(file) → u32New — reads bytes 4–8 of page 0
write_dead_tuple_count(file, count)New — overwrites bytes 4–8 of page 0
increment_dead_tuple_count(file, delta)New — saturating-add to the stored counter

Added struct: TableHeader { page_count: u32, dead_tuple_count: u32 } for typed header access.


src/backend/disk/disk_manager.rs

Modified by the disk/heap team as part of the integration handshake. Exposes update_header_page and read_header_page used by api.rs when persisting fsm_page_count after a rebuild.


src/backend/heap/heap_manager.rs

Modified by the heap team to support HeapManager::open and HeapManager::insert_tuple, which insert_raw_tuple in api.rs delegates to. Also integrates FSM::build_from_heap for FSM rebuild after compaction.


src/backend/executor/seq_scan.rsshow_tuples

Updated to check the SLOT_FLAG_DELETED bit on each item-ID entry while scanning. Soft-deleted tuples are now completely invisible to Show Tuples.

// Before: all slots were shown
// After: skip any slot where flags & SLOT_FLAG_DELETED != 0
if item_flags & SLOT_FLAG_DELETED != 0 {
continue;
}

src/backend/mod.rs

Registered three new sub-modules:

pub mod visibility_map;
pub mod page; // already existed; page_lock module added inside
pub mod heap {
pub mod autovacuum; // added
// ...
}
pub mod log {
pub mod operation_log; // added
}

src/frontend/menu.rs

Three new menu options added (options 9, 10, 11; Exit moved to 12):

9.  Delete Tuples
10. Update Tuples
11. Compact Table
12. Exit

src/frontend/data_cmd.rs

Three new command handler functions added:

FunctionDescription
delete_tuples_cmdPrompts for table, WHERE clause, RETURNING flag; calls delete_tuples
update_tuples_cmdPrompts for table, SET clause, WHERE clause, RETURNING flag; calls update_tuples
compact_table_cmdPrompts for table name; calls compaction_table

src/main.rs

Background autovacuum worker pool is now started before the menu loop:

let av_handles = storage_manager::autovacuum::start(Arc::clone(&shutdown));
// ... menu runs ...
shutdown.store(true, Ordering::SeqCst);
for handle in av_handles { handle.join(); }

The shutdown flag is shared via Arc<AtomicBool> so the menu's Exit command signals all workers cleanly.