Rust Extensions¶
Extend Grafeo with custom Rust code for maximum performance.
Why Rust Extensions?¶
- Performance - Native speed for computationally intensive operations
- Type Safety - Compile-time guarantees
- Direct Access - Access to internal Grafeo APIs
- Integration - Use any Rust crate
Creating an Extension Crate¶
Cargo.toml¶
[package]
name = "my-grafeo-extension"
version = "0.1.0"
edition = "2024"
[dependencies]
grafeo-core = "0.1"
grafeo-engine = "0.1"
Extension Code¶
use grafeo_core::graph::LpgStore;
use grafeo_engine::{Database, Session};
/// Custom graph analysis function
pub fn analyze_connectivity(db: &Database) -> ConnectivityReport {
let session = db.session().unwrap();
// Access the underlying graph store
let store = session.graph_store();
let node_count = store.node_count();
let edge_count = store.edge_count();
let avg_degree = (edge_count as f64 * 2.0) / node_count as f64;
ConnectivityReport {
nodes: node_count,
edges: edge_count,
average_degree: avg_degree,
}
}
pub struct ConnectivityReport {
pub nodes: usize,
pub edges: usize,
pub average_degree: f64,
}
Accessing Internal APIs¶
Graph Store¶
use grafeo_core::graph::lpg::LpgStore;
fn process_graph(store: &LpgStore) {
// Iterate over nodes
for node in store.nodes() {
println!("Node: {:?}", node.id());
for label in node.labels() {
println!(" Label: {}", label);
}
}
// Iterate over edges
for edge in store.edges() {
println!("Edge: {} -[{}]-> {}",
edge.source(),
edge.edge_type(),
edge.target()
);
}
}
Index Access¶
use grafeo_core::index::BTreeIndex;
fn query_index(index: &BTreeIndex<String, NodeId>) {
// Range query
let results = index.range("A".."B");
for (key, node_id) in results {
println!("{}: {:?}", key, node_id);
}
}
Execution Engine¶
use grafeo_core::execution::{DataChunk, Pipeline};
fn custom_operator(chunk: DataChunk) -> DataChunk {
// Process data chunk
chunk.filter(|row| row.get("age").as_int() > 30)
}
Building and Using¶
Build¶
Use in Application¶
use my_grafeo_extension::analyze_connectivity;
let db = Database::open("my_graph.db")?;
let report = analyze_connectivity(&db);
println!("Nodes: {}", report.nodes);
println!("Edges: {}", report.edges);
println!("Avg Degree: {:.2}", report.average_degree);
Exposing to Python¶
Use PyO3 to expose Rust extensions to Python:
use pyo3::prelude::*;
#[pyfunction]
fn analyze_connectivity_py(db: &PyGrafeoDB) -> PyResult<PyDict> {
let report = analyze_connectivity(db.inner());
let dict = PyDict::new(py);
dict.set_item("nodes", report.nodes)?;
dict.set_item("edges", report.edges)?;
dict.set_item("average_degree", report.average_degree)?;
Ok(dict)
}
#[pymodule]
fn my_extension(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(analyze_connectivity_py, m)?)?;
Ok(())
}