marsdb-graph 0.3.0

Property graph model and CRUD storage layer used internally by MarsDB.
Documentation
use marsdb_storage::{ReadableTable, Txn, WriteTransaction};

use crate::error::GraphError;
use crate::id::next_id;

/// Look up (or allocate) the u32 id interned for `label`, inside a write txn.
pub(crate) fn intern_label(write_txn: &WriteTransaction, label: &str) -> Result<u32, GraphError> {
    {
        let l2i = write_txn.open_table(marsdb_storage::tables::LABEL_TO_ID)?;
        let existing = l2i.get(label)?.map(|g| g.value());
        if let Some(existing) = existing {
            return Ok(existing);
        }
    }
    let id = next_id(write_txn, "next_label_id")? as u32;
    {
        let mut l2i = write_txn.open_table(marsdb_storage::tables::LABEL_TO_ID)?;
        l2i.insert(label, id)?;
    }
    {
        let mut i2l = write_txn.open_table(marsdb_storage::tables::ID_TO_LABEL)?;
        i2l.insert(id, label)?;
    }
    Ok(id)
}

/// Resolve a previously interned label id back to its string. Read-only —
/// takes `Txn` so it works against either a `WriteTransaction` (a write
/// statement's crash-safety boundary — see `GraphStore::begin_write`) or a
/// `ReadTransaction` (a read-only statement, run without contending for
/// redb's single-writer lock — see `GraphStore::begin_read`).
pub(crate) fn resolve_label(txn: Txn, label_id: u32) -> Result<String, GraphError> {
    let i2l = txn.open_table(marsdb_storage::tables::ID_TO_LABEL)?;
    let value = i2l
        .get(label_id)?
        .expect("label id present in nodes/edges table must be interned");
    Ok(value.value().to_string())
}

/// Look up the id for `label` without allocating one. Returns `None` if the
/// label has never been used, meaning no rows can reference it. Read-only —
/// see `resolve_label`'s doc comment for why this takes `Txn`.
pub(crate) fn lookup_label_id(txn: Txn, label: &str) -> Result<Option<u32>, GraphError> {
    let l2i = txn.open_table(marsdb_storage::tables::LABEL_TO_ID)?;
    let found = l2i.get(label)?.map(|g| g.value());
    Ok(found)
}