Skip to main content

speck_core/storage/
journal.rs

1//! Transaction journal for atomic updates
2//! 
3//! Records operations to allow recovery from interrupted writes.
4
5use crate::flash::{Flash, PageId};
6use crate::error::Result;
7
8/// Transaction record
9#[derive(Clone, Debug)]
10pub struct Transaction {
11    slot: usize,
12    address: usize,
13    expected_size: usize,
14    written: usize,
15    committed: bool,
16}
17
18impl Transaction {
19    /// Create new transaction
20    pub fn new(slot: usize, address: usize, expected_size: usize) -> Self {
21        Self {
22            slot,
23            address,
24            expected_size,
25            written: 0,
26            committed: false,
27        }
28    }
29    
30    /// Get target address
31    pub fn address(&self) -> usize {
32        self.address
33    }
34    
35    /// Record bytes written
36    pub fn record_write(&mut self, bytes: usize) {
37        self.written += bytes;
38    }
39    
40    /// Check if complete
41    pub fn is_complete(&self) -> bool {
42        self.written >= self.expected_size && self.committed
43    }
44}
45
46/// Simple journal for crash recovery
47pub struct Journal {
48    region: core::ops::Range<usize>,
49}
50
51impl Journal {
52    /// Create journal in specified region
53    pub fn new(region: core::ops::Range<usize>) -> Self {
54        Self { region }
55    }
56    
57    /// Log transaction start
58    pub fn log_start(&mut self, flash: &mut Flash, tx: &Transaction) -> Result<()> {
59        let entry = JournalEntry::Start {
60            slot: tx.slot as u8,
61            size: tx.expected_size as u32,
62        };
63        self.append(flash, entry)
64    }
65    
66    /// Log transaction commit
67    pub fn commit(&mut self, tx: Transaction, flash: &mut Flash) -> Result<()> {
68        let entry = JournalEntry::Commit {
69            slot: tx.slot as u8,
70        };
71        self.append(flash, entry)
72    }
73    
74    fn append(&mut self, flash: &mut Flash, entry: JournalEntry) -> Result<()> {
75        // Simple circular buffer implementation would go here
76        // For now, just reserve the capability
77        let _ = (flash, entry);
78        Ok(())
79    }
80}
81
82#[derive(Clone, Debug)]
83enum JournalEntry {
84    Start { slot: u8, size: u32 },
85    Commit { slot: u8 },
86    Abort { slot: u8 },
87}