wasm-dbms-memory 0.8.2

Memory abstraction and page management for the wasm-dbms framework
Documentation
// Rust guideline compliant 2026-02-28

use wasm_dbms_api::prelude::{MemoryResult, Page};

use super::FreeSegmentsTable;
use crate::MemoryAccess;

/// An iterator which yields all the [`FreeSegmentsTable`]s.
pub struct TablesIter<'a, MA>
where
    MA: MemoryAccess,
{
    /// Tracks the current index.
    index: usize,
    /// Reference to the memory access implementor.
    mm: &'a mut MA,
    /// The pages to iterate over.
    pages: &'a [Page],
}

impl<'a, MA> TablesIter<'a, MA>
where
    MA: MemoryAccess,
{
    /// Creates a new [`TablesIter`].
    pub fn new(pages: &'a [Page], mm: &'a mut MA) -> Self {
        Self {
            index: 0,
            mm,
            pages,
        }
    }
}

impl<MA> Iterator for TablesIter<'_, MA>
where
    MA: MemoryAccess,
{
    type Item = MemoryResult<FreeSegmentsTable>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.index >= self.pages.len() {
            return None;
        }
        let page = self.pages[self.index];
        self.index += 1;

        // read next page
        Some(FreeSegmentsTable::load(page, self.mm))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{HeapMemoryProvider, MemoryManager};

    #[test]
    fn test_tables_iter_empty() {
        let mut mm = MemoryManager::init(HeapMemoryProvider::default());
        let pages = vec![];
        let mut iter = TablesIter::new(&pages, &mut mm);
        assert!(iter.next().is_none());
    }

    #[test]
    fn test_should_iter_tables() {
        const COUNT: usize = 5;
        let mut mm = MemoryManager::init(HeapMemoryProvider::default());
        let mut pages = Vec::new();
        for _ in 0..COUNT {
            let page = mm.allocate_page().expect("Failed to allocate page");
            let mut table = FreeSegmentsTable::load(page, &mut mm).expect("Failed to load page");
            // insert a segment
            table
                .insert_free_segment(100 + page as Page, 0, 50, &mut mm)
                .expect("Failed to insert segment");
            pages.push(page);
        }

        let mut iter = TablesIter::new(&pages, &mut mm);
        for expected_page in &pages {
            let table_result = iter.next();
            assert!(table_result.is_some());
            let table = table_result.unwrap().expect("Failed to load table");
            // should have a segment
            let segment = table.find(|_| true).expect("Failed to find segment");
            assert_eq!(segment.page, expected_page + 100);
        }
        assert!(iter.next().is_none());
    }
}