This project implements a high-performance, fixed-size Write-Back Block Cache designed for a B-tree based filesystem. The core objective is to provide
The cache operates as a fixed-size memory pool (an array of cache_entry_t structs) whose size is dynamically configured based on available system RAM during initialization.
The design is a classic example of balancing Performance (via hash maps and lists) and Memory Boundary (via the fixed array).
| Data Structure | Role | Optimization | Complexity |
|---|---|---|---|
Fixed-Size Array (cache->cache) |
Physical Memory Pool | The backing store for all block data and metadata. Enforces a strict memory limit. |
|
Hash Map 1 (PCI) (PCI_HM) |
Primary Cache Index | Maps block_number to its array index/slot. Answers: "Is block X in the cache?" |
|
Doubly-Linked List (LRU_List) |
Eviction Mechanism | Tracks access recency. Head is MRU, Tail is LRU. Used for selecting a victim block on cache miss. |
|
Singly-Linked List (FL_LL) |
Free Slot Allocator | Stores indices of currently unused slots in the Fixed Array. |
|
Hash Map 2 (DL) (DL_HM) |
fsync Optimizer |
Maps inode_number to a list of its associated dirty blocks. Essential for efficient, fine-grained durability. |
fsync
|
The cache employs a Write-Back policy for high performance, where modifications are buffered in memory and marked with a dirty_bit. Durability is guaranteed through explicit synchronization calls:
-
cache_fsync(inum): Uses the Per-Inode Dirty List (DL) to quickly find and write back only the dirty blocks belonging to a specific inode, making it an$\text{O}(\text{Dirty Blocks for file})$ operation. -
cache_sync(): Uses the Global Dirty List (GDL) to write back all dirty blocks currently in the cache.
The implementation prioritizes data sanitization upon freeing memory to prevent information leakage:
- Secure Wiping (
arc4random_buf): The BSD functionarc4random_bufis used to overwrite the memory of all dynamically allocated structures (linked list nodes, hash map nodes, and the actual page data) with cryptographically secure random bytes immediately before callingfree(). This is critical for cache entries that may contain sensitive data before being evicted.
The project uses a simple Makefile and requires the bsd library for arc4random_buf.
To compile the project:
clang -lbsd -g -o cache_test *.c
dd if=/dev/zero of=my.img bs=1M count=2 # Creates a 2MB disk image for testing