sinistra 0.1.0-202603071957

A generic graph framework with pluggable storage and topology and streaming graph algorithms.
Documentation
use std::sync::atomic::{AtomicU32, Ordering};

use crate::graph::{Checked, EdgeHandle, Storage, StorageMut, VertexHandle};

static DISCRIMINANT_COUNTER: AtomicU32 = AtomicU32::new(10_000);

#[derive(Debug, Default, Clone)]
pub struct VecStorage<V, E> {
    discriminant: u32,
    vertices: Vec<Option<V>>,
    edges: Vec<Option<E>>,
}

impl<V, E> VecStorage<V, E> {
    pub fn new() -> Self {
        Self {
            discriminant: DISCRIMINANT_COUNTER.fetch_add(1, Ordering::Relaxed),
            vertices: Vec::new(),
            edges: Vec::new(),
        }
    }

    fn checked_vertex(&self, handle: VertexHandle) -> Option<Checked<VertexHandle>> {
        let checked = Checked::graph_and_generation(handle, self.discriminant)?;
        if checked.index() >= self.vertices.len() {
            return None;
        }

        Some(checked)
    }

    fn checked_edge(&self, handle: EdgeHandle) -> Option<Checked<EdgeHandle>> {
        let checked = Checked::graph_and_generation(handle, self.discriminant)?;
        if checked.index() >= self.edges.len() {
            return None;
        }

        Some(checked)
    }
}

impl<V, E> Storage for VecStorage<V, E> {
    type Vertex = V;
    type Edge = E;

    fn vertex(&self, handle: VertexHandle) -> Option<&Self::Vertex> {
        let checked = self.checked_vertex(handle)?;
        self.vertices.get(checked.index())?.as_ref()
    }

    fn edge(&self, handle: EdgeHandle) -> Option<&Self::Edge> {
        let checked = self.checked_edge(handle)?;
        self.edges.get(checked.index())?.as_ref()
    }
}

impl<V, E> StorageMut for VecStorage<V, E> {
    fn vertex_mut(&mut self, handle: VertexHandle) -> Option<&mut Self::Vertex> {
        let checked = self.checked_vertex(handle)?;
        self.vertices.get_mut(checked.index())?.as_mut()
    }

    fn edge_mut(&mut self, handle: EdgeHandle) -> Option<&mut Self::Edge> {
        let checked = self.checked_edge(handle)?;
        self.edges.get_mut(checked.index())?.as_mut()
    }

    fn add_vertex(&mut self, vertex: Self::Vertex) -> VertexHandle {
        let handle = VertexHandle::new(self.vertices.len() as u64, 1, self.discriminant);
        self.vertices.push(Some(vertex));
        handle
    }

    fn add_edge(&mut self, edge: Self::Edge) -> EdgeHandle {
        let handle = EdgeHandle::new(self.edges.len() as u64, 1, self.discriminant);
        self.edges.push(Some(edge));
        handle
    }

    fn set_vertex(&mut self, handle: VertexHandle, vertex: Self::Vertex) -> Option<Self::Vertex> {
        let checked = self.checked_vertex(handle)?;
        self.vertices[checked.index()].replace(vertex)
    }

    fn set_edge(&mut self, handle: EdgeHandle, edge: Self::Edge) -> Option<Self::Edge> {
        let checked = self.checked_edge(handle)?;
        self.edges[checked.index()].replace(edge)
    }

    fn remove_vertex(&mut self, handle: VertexHandle) -> Option<Self::Vertex> {
        let checked = self.checked_vertex(handle)?;
        self.vertices[checked.index()].take()
    }

    fn remove_edge(&mut self, handle: EdgeHandle) -> Option<Self::Edge> {
        let checked = self.checked_edge(handle)?;
        self.edges[checked.index()].take()
    }
}