inc-complete 0.10.3

A library for writing incremental computations that re-execute the minimum number of steps when an input is changed
Documentation
use std::sync::{
    Arc,
    atomic::{AtomicU32, Ordering},
};

use parking_lot::Mutex;
use serde::{Deserialize, Serialize, ser::SerializeStruct};

use crate::Cell;

use super::Db;

impl<Storage> serde::Serialize for Db<Storage>
where
    Storage: serde::Serialize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let mut cells = Vec::with_capacity(self.cells.len());

        for item in self.cells.iter() {
            let value = item.value();
            let input_dependencies: Vec<_> = value.input_dependencies.iter().copied().collect();

            cells.push((
                *item.key(),
                CellDataDeserialize {
                    computation_id: value.computation_id,
                    last_updated_version: value.last_updated_version,
                    last_run_version: value.last_run_version,
                    last_verified_version: value.last_verified_version,
                    dependencies: value.dependencies.clone(),
                    input_dependencies,
                },
            ));
        }

        let version = self.version.load(Ordering::SeqCst);
        let next_cell = self.next_cell.load(Ordering::SeqCst);

        let mut s = serializer.serialize_struct("Db", 4)?;
        s.serialize_field("version", &version)?;
        s.serialize_field("next_cell", &next_cell)?;
        s.serialize_field("cells", &cells)?;
        s.serialize_field("storage", &self.storage)?;
        s.end()
    }
}

#[derive(Deserialize)]
#[serde(rename = "Db")]
struct DbDeserialize<Storage> {
    version: u32,
    next_cell: u32,
    cells: Vec<(Cell, CellDataDeserialize)>,
    storage: Storage,
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "CellData")]
struct CellDataDeserialize {
    computation_id: u32,
    last_updated_version: u32,
    #[serde(default)]
    last_run_version: u32,
    last_verified_version: u32,
    dependencies: Vec<Cell>,
    input_dependencies: Vec<Cell>,
}

impl<'de, Storage> serde::Deserialize<'de> for Db<Storage>
where
    Storage: serde::Deserialize<'de>,
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let db = DbDeserialize::deserialize(deserializer)?;

        let cells = dashmap::DashMap::with_capacity(db.cells.len());

        for (cell, data) in db.cells {
            cells.insert(
                cell,
                crate::cell::CellData {
                    computation_id: data.computation_id,
                    last_updated_version: data.last_updated_version,
                    last_run_version: data.last_run_version,
                    last_verified_version: data.last_verified_version,
                    dependencies: data.dependencies,
                    input_dependencies: data.input_dependencies.into_iter().collect(),
                    lock: Arc::new(Mutex::new(())),
                },
            );
        }

        Ok(Db {
            cells,
            version: AtomicU32::new(db.version),
            next_cell: AtomicU32::new(db.next_cell),
            cell_locks: Default::default(),
            storage: db.storage,
        })
    }
}