overgraph 0.11.0

An absurdly fast embedded graph database. Pure Rust, sub-microsecond reads.
Documentation
use crate::types::EdgeRecord;

pub(crate) const EDGE_WEIGHT_INDEX_LOGICAL_NAME: &str = "edge_weight_index";
pub(crate) const EDGE_UPDATED_AT_INDEX_LOGICAL_NAME: &str = "edge_updated_at_index";
pub(crate) const EDGE_VALID_FROM_INDEX_LOGICAL_NAME: &str = "edge_valid_from_index";
pub(crate) const EDGE_VALID_TO_INDEX_LOGICAL_NAME: &str = "edge_valid_to_index";

pub(crate) const EDGE_WEIGHT_INDEX_ENTRY_SIZE: usize = 16;
pub(crate) const EDGE_I64_METADATA_INDEX_ENTRY_SIZE: usize = 20;

pub(crate) type EdgeWeightIndexEntry = (u32, u32, u64);
pub(crate) type EdgeI64MetadataIndexEntry = (u32, i64, u64);

#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub(crate) struct EdgeMetadataIndexEntries {
    pub(crate) weight: Vec<EdgeWeightIndexEntry>,
    pub(crate) updated_at: Vec<EdgeI64MetadataIndexEntry>,
    pub(crate) valid_from: Vec<EdgeI64MetadataIndexEntry>,
    pub(crate) valid_to: Vec<EdgeI64MetadataIndexEntry>,
}

impl EdgeMetadataIndexEntries {
    pub(crate) fn with_capacity(edge_count: usize) -> Self {
        Self {
            weight: Vec::with_capacity(edge_count),
            updated_at: Vec::with_capacity(edge_count),
            valid_from: Vec::with_capacity(edge_count),
            valid_to: Vec::with_capacity(edge_count),
        }
    }

    pub(crate) fn push(
        &mut self,
        label_id: u32,
        updated_at: i64,
        weight: f32,
        valid_from: i64,
        valid_to: i64,
        edge_id: u64,
    ) {
        if let Some(weight_key) = encode_edge_weight_key(weight) {
            self.weight.push((label_id, weight_key, edge_id));
        }
        self.updated_at.push((label_id, updated_at, edge_id));
        self.valid_from.push((label_id, valid_from, edge_id));
        self.valid_to.push((label_id, valid_to, edge_id));
    }

    pub(crate) fn sort_all(&mut self) {
        self.weight.sort_unstable();
        self.updated_at.sort_unstable();
        self.valid_from.sort_unstable();
        self.valid_to.sort_unstable();
    }
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub(crate) struct EdgeMetadataCandidate {
    pub(crate) edge_id: u64,
    pub(crate) from: u64,
    pub(crate) to: u64,
    pub(crate) label_id: u32,
    pub(crate) updated_at: i64,
    pub(crate) weight: f32,
    pub(crate) valid_from: i64,
    pub(crate) valid_to: i64,
}

impl EdgeMetadataCandidate {
    pub(crate) fn from_edge(edge: &EdgeRecord) -> Self {
        Self {
            edge_id: edge.id,
            from: edge.from,
            to: edge.to,
            label_id: edge.label_id,
            updated_at: edge.updated_at,
            weight: edge.weight,
            valid_from: edge.valid_from,
            valid_to: edge.valid_to,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct RangeBoundFlags<T> {
    pub(crate) lower: Option<T>,
    pub(crate) lower_inclusive: bool,
    pub(crate) upper: Option<T>,
    pub(crate) upper_inclusive: bool,
}

impl<T> RangeBoundFlags<T> {
    pub(crate) fn inclusive(lower: Option<T>, upper: Option<T>) -> Self {
        Self {
            lower,
            lower_inclusive: true,
            upper,
            upper_inclusive: true,
        }
    }
}

pub(crate) fn encode_edge_weight_key(weight: f32) -> Option<u32> {
    if weight.is_nan() {
        return None;
    }
    let normalized = if weight == 0.0 { 0.0 } else { weight };
    let bits = normalized.to_bits();
    Some(if bits & (1u32 << 31) != 0 {
        !bits
    } else {
        bits ^ (1u32 << 31)
    })
}

pub(crate) fn i64_matches_bounds(value: i64, bounds: RangeBoundFlags<i64>) -> bool {
    if let Some(lower) = bounds.lower {
        if bounds.lower_inclusive {
            if value < lower {
                return false;
            }
        } else if value <= lower {
            return false;
        }
    }
    if let Some(upper) = bounds.upper {
        if bounds.upper_inclusive {
            if value > upper {
                return false;
            }
        } else if value >= upper {
            return false;
        }
    }
    true
}

pub(crate) fn weight_matches_bounds(weight: f32, bounds: RangeBoundFlags<f32>) -> bool {
    if weight.is_nan() {
        return false;
    }
    if let Some(lower) = bounds.lower {
        if bounds.lower_inclusive {
            if weight < lower {
                return false;
            }
        } else if weight <= lower {
            return false;
        }
    }
    if let Some(upper) = bounds.upper {
        if bounds.upper_inclusive {
            if weight > upper {
                return false;
            }
        } else if weight >= upper {
            return false;
        }
    }
    true
}