Skip to main content

speck_core/storage/
layout.rs

1//! Storage layout calculation
2
3use crate::error::{Error, Result};
4use super::StorageConfig;
5
6/// Calculated layout of flash regions
7#[derive(Clone, Debug)]
8pub struct StorageLayout {
9    capacity: usize,
10    page_size: usize,
11    metadata_start: usize,
12    journal_start: usize,
13    slot_start: usize,
14    slot_size: usize,
15}
16
17impl StorageLayout {
18    /// Calculate layout for given capacity and config
19    pub fn new(capacity: usize, config: &StorageConfig) -> Result<Self> {
20        let page_size = 4096; // Assume 4KB pages
21        
22        // Reserve first page for metadata
23        let metadata_start = 0;
24        let journal_start = page_size;
25        
26        // Reserve 1 page for journal
27        let slot_start = journal_start + page_size;
28        let available = capacity.saturating_sub(slot_start);
29        
30        let slot_size = available / config.module_slots;
31        if slot_size < config.max_module_size {
32            return Err(Error::Storage(format!(
33                "insufficient space: need {} per slot, have {}",
34                config.max_module_size, slot_size
35            )));
36        }
37        
38        Ok(Self {
39            capacity,
40            page_size,
41            metadata_start,
42            journal_start,
43            slot_start,
44            slot_size,
45        })
46    }
47    
48    /// Get metadata region address
49    pub fn metadata_address(&self) -> usize {
50        self.metadata_start
51    }
52    
53    /// Get journal region
54    pub fn journal_region(&self) -> core::ops::Range<usize> {
55        self.journal_start..self.slot_start
56    }
57    
58    /// Get slot start address
59    pub fn slot_address(&self, slot: usize) -> usize {
60        self.slot_start + slot * self.slot_size
61    }
62    
63    /// Get size of each slot
64    pub fn slot_size(&self) -> usize {
65        self.slot_size
66    }
67}