neug-rust 0.1.0

Safe Rust bindings for the NeuG C++ graph database engine
# neug-rust

A Safe Rust wrapper for the [alibaba/neug](https://github.com/alibaba/neug) C++ graph database engine.

**High-performance embedded graph database for analytics and real-time transactions.**  
[graphscope.io/neug](https://graphscope.io/docs/neug)

## Overview

This project provides high-level, idiomatic Rust bindings to the `neug` C++ library. It is designed as a Cargo workspace with two main crates:

*   `neug-sys`: Contains the low-level, unsafe FFI bindings generated by `bindgen` and the build script that compiles the underlying C++ library using CMake.
*   `neug-rust` (in the `neug-bindings` directory): Provides a safe, user-friendly Rust API (`Database`, `Connection`, etc.) that wraps the raw C++ pointers and handles memory management automatically.

> **Note:** The architecture and intelligent CMake build mechanism of this repository were heavily inspired by the excellent [zvec-rust-binding]https://github.com/igobypenn/zvec-rust-binding/ project. Like `zvec`, our build script will automatically download the required C++ source code during `cargo build` if it is not present locally, bypassing the crates.io size limits.

## Prerequisites

Building `neug` from source requires several C++ dependencies installed on your system, as defined by its CMake configuration. Please ensure you have the following installed (e.g., via `brew` on macOS or `apt` on Linux):

- CMake (>= 3.16)
- C++20 compatible compiler (Clang/GCC)
- OpenSSL
- gflags, glog

*Note: Heavy dependencies like Apache Arrow, Protobuf, and Abseil are automatically downloaded and built by the internal CMake script.*

## Getting Started

### Local Development

1. **Clone the repository with submodules:**
   ```bash
   git clone --recursive https://github.com/miofthena/neug-rust.git
   cd neug-rust
   ```
   *(If already cloned, run `git submodule update --init --recursive`)*

2. **Build the workspace:**
   ```bash
   cargo build
   ```
   *Note: The first build will take a significant amount of time (often >5 minutes) as it compiles the entire C++ codebase and its dependencies.*

3. **Run Tests:**
   ```bash
   cargo test
   ```

4. **Run Examples:**
   ```bash
   cargo run --example simple_example
   cargo run --example crud_operations
   cargo run --example parallel_query
   ```

### Speeding up C++ Compilation
To prevent the underlying C++ library (`neug-cpp`) from compiling from scratch on subsequent builds or across workspaces, it is highly recommended to install a compiler cache tool. Our build script automatically detects and utilizes them:
*   Install `sccache` (via `cargo install sccache` or brew/apt)
*   Or install `ccache` (via brew/apt)

## Performance & Benchmarks

The library is continuously benchmarked using `criterion` to measure the overhead introduced by the Rust FFI boundary and data preparation. Because the wrappers are extremely thin, the actual dispatch overhead is practically non-existent.

Running the realistic workloads (`cargo bench`) on an Apple Silicon (M-series) chip yields the following **Rust Wrapper Overhead**:

*   **Connection Lifecycle:** `~1.85 µs` - The time required to initialize and teardown a safe Rust connection proxy pointing to the C++ engine.
*   **Query Dispatch (Parse & Execute):** `~98.2 µs` - The total time it takes to allocate strings in Rust, pass them across the FFI boundary, and have the C++ engine parse and execute a simple Cypher `MATCH` query.

*(Note: These benchmarks measure the overhead of the **Rust bindings**, not the underlying `neug` C++ engine's execution time, as that varies by workload).*

## Usage Example

```rust
use neug_rust::{Database, Mode};
use tempfile::tempdir;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let dir = tempdir()?;
    
    // 1. Initialize the database
    let mut db = Database::open(dir.path(), Mode::ReadWrite)?;

    // 2. Open a connection
    let mut conn = db.connect()?;

    // 3. Execute DDL / DML queries
    conn.execute("CREATE NODE TABLE person(id INT64, name STRING, age INT64, PRIMARY KEY(id));")?;
    conn.execute("CREATE REL TABLE knows(FROM person TO person, weight DOUBLE);")?;

    // 4. Query data
    let _result = conn.execute("MATCH (n)-[e]-(m) return count(e);")?;
    println!("Queries executed successfully.");

    // The database and connections are automatically closed when dropped.
    Ok(())
}
```

## Contributing

1. Add high-level, safe Rust abstractions in `neug-bindings/src/`.
2. Ensure you adhere to standard Rust community practices (e.g., `cargo fmt`, `cargo clippy`).
3. Add tests to verify your safe wrappers in `neug-bindings/tests/`.

## License

This wrapper is licensed under the same terms as the `neug` project (Apache License 2.0).