Repository: google/OpenSK
File: src/embedded_flash/store/mod.rs (Rust)

Code before:
        }
        debug_assert!(self.blank_page != self.format.num_pages);
    }

    /// Marks an entry as deleted.
    ///
    /// The provided index must point to the beginning of an entry.
    fn delete_index(&mut self, index: Index) {
        self.update_word(index, |format, word| format.set_deleted(word));
        self.wipe_sensitive_data(index);
    }

    /// Wipes the data of a sensitive entry.
    ///
    /// If the entry at the provided index is sensitive, overwrites the data with zeroes. Otherwise,
    /// does nothing.
    fn wipe_sensitive_data(&mut self, mut index: Index) {
        let entry = self.read_entry(index);
        debug_assert!(self.format.is_present(entry));
        debug_assert!(self.format.is_deleted(entry));
        if self.format.is_internal(entry) || !self.format.is_sensitive(entry) {
            // No need to wipe the data.
            return;
        }
        let gap = self.format.entry_gap(entry);
        let data = &entry[gap.start..][..gap.length];
        if data.iter().all(|&byte| byte == 0x00) {
            // The data is already wiped.
            return;
        }
        index.byte += gap.start;
        self.storage
            .write_slice(index, &vec![0; gap.length])
            .unwrap();
    }

    /// Finds a page with enough free space.
    ///
    /// Returns an index to the free space of a page which can hold an entry of `length` bytes. If
    /// necessary, pages may be compacted to free space. In that case, if provided, the `old_index`
    /// is updated according to compaction.
    fn find_slot_for_write(
        &mut self,
        length: usize,
        mut old_index: Option<&mut Index>,
    ) -> Result<Index, StoreError> {
        loop {
            if let Some(index) = self.choose_slot_for_write(length) {
                return Ok(index);
            }
            match self.choose_page_for_compact() {

Review comment (suggestion):
Since the next line iterates on the bytes anyway, I think it'd be more readable as `.iter().skip(gap.start).take(gap.length)`. I think that the "double slicing" `entry[gap.start..][..gap.length]` is more confusing.

Code after:
                } else if !self.format.is_committed(entry) {
                    // Finish complete but uncommitted operations.
                    self.commit_index(entry_index)
                }
            }
        }
    }

    /// Initializes uninitialized pages.
    fn initialize_storage(&mut self) {
        for page in 0..self.format.num_pages {
            let (header, index) = self.read_page_header(page);
            if self.format.is_initialized(header) {
                // Update blank page.
                let first_entry = self.read_entry(index);
                if !self.format.is_present(first_entry) {
                    self.blank_page = page;
                }
            } else {
                // We set the erase count to zero the very first time we initialize a page.
                self.initialize_page(page, 0);
            }
        }
        debug_assert!(self.blank_page != self.format.num_pages);
    }

    /// Marks an entry as deleted.
    ///
    /// The provided index must point to the beginning of an entry.
    fn delete_index(&mut self, index: Index) {
        self.update_word(index, |format, word| format.set_deleted(word));
        self.wipe_sensitive_data(index);
    }

    /// Wipes the data of a sensitive entry.
    ///
    /// If the entry at the provided index is sensitive, overwrites the data with zeroes. Otherwise,
    /// does nothing.
    fn wipe_sensitive_data(&mut self, mut index: Index) {
        let entry = self.read_entry(index);
        debug_assert!(self.format.is_present(entry));
        debug_assert!(self.format.is_deleted(entry));
        if self.format.is_internal(entry) || !self.format.is_sensitive(entry) {
            // No need to wipe the data.
            return;
        }
        let gap = self.format.entry_gap(entry);
        let data = gap.slice(entry);
        if data.iter().all(|&byte| byte == 0x00) {
            // The data is already wiped.
            return;