state_tree/
patch.rs

1/// A patch to be applied to a flat state storage from old storage.
2/// 
3/// A patch represents a flat array copy operation from the source data storage
4/// to the destination data storage.
5#[derive(Debug, PartialEq, Eq, Clone, Hash)]
6pub struct CopyFromPatch {
7    /// Starting address in the source data storage (index from the beginning of the array)
8    pub src_addr: usize,
9    /// Starting address in the destination data storage
10    pub dst_addr: usize,
11    /// Size of data to copy (in u64 units)
12    pub size: usize,
13}
14
15/// Apply patches to a new flat array.
16///
17/// # Arguments
18/// * `new_storage` - Destination flat array with the new structure (initialized with zeros)
19/// * `old_storage` - Source flat array with the old structure
20/// * `patches` - List of patches generated by the `diff` function
21///
22/// # Panics
23/// May panic if the addresses or sizes in the patches are invalid.
24/// (This should not happen if `diff` is correctly implemented)
25pub fn apply_patches(new_storage: &mut [u64], old_storage: &[u64], patches: &[CopyFromPatch]) {
26    for patch in patches {
27        let src_end = patch.src_addr + patch.size;
28        let dst_end = patch.dst_addr + patch.size;
29        
30        debug_assert!(
31            src_end <= old_storage.len(),
32            "Source address range [{}, {}) exceeds old storage size {}",
33            patch.src_addr,
34            src_end,
35            old_storage.len()
36        );
37        debug_assert!(
38            dst_end <= new_storage.len(),
39            "Destination address range [{}, {}) exceeds new storage size {}",
40            patch.dst_addr,
41            dst_end,
42            new_storage.len()
43        );
44        
45        // Perform flat array copy
46        new_storage[patch.dst_addr..dst_end]
47            .copy_from_slice(&old_storage[patch.src_addr..src_end]);
48    }
49}