git-subtree-dir: vendor/ruvector git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
844 lines
20 KiB
Markdown
844 lines
20 KiB
Markdown
# SPARC Phase 5: Completion - Integration & Deployment
|
|
|
|
## Overview
|
|
|
|
This phase covers the final integration, deployment, documentation, and release preparation for the `ruvector-mincut` crate implementing subpolynomial-time dynamic minimum cut algorithms.
|
|
|
|
## 1. Integration with ruvector Ecosystem
|
|
|
|
### 1.1 Workspace Integration
|
|
|
|
**Update root `Cargo.toml`**:
|
|
```toml
|
|
[workspace]
|
|
members = [
|
|
"crates/ruvector",
|
|
"crates/ruvector-graph",
|
|
"crates/ruvector-mincut", # Add new crate
|
|
# ... other crates
|
|
]
|
|
|
|
[workspace.dependencies]
|
|
ruvector-mincut = { version = "0.1.0", path = "crates/ruvector-mincut" }
|
|
```
|
|
|
|
**Create `crates/ruvector-mincut/Cargo.toml`**:
|
|
```toml
|
|
[package]
|
|
name = "ruvector-mincut"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
authors = ["RuVector Team"]
|
|
description = "Subpolynomial-time dynamic minimum cut algorithm"
|
|
license = "MIT OR Apache-2.0"
|
|
repository = "https://github.com/ruvnet/ruvector"
|
|
keywords = ["graph", "minimum-cut", "dynamic", "algorithms"]
|
|
categories = ["algorithms", "data-structures"]
|
|
|
|
[dependencies]
|
|
ruvector-graph = { workspace = true }
|
|
thiserror = "1.0"
|
|
smallvec = "1.11"
|
|
typed-arena = "2.0"
|
|
|
|
[dependencies.serde]
|
|
version = "1.0"
|
|
features = ["derive"]
|
|
optional = true
|
|
|
|
[dev-dependencies]
|
|
criterion = "0.5"
|
|
proptest = "1.4"
|
|
quickcheck = "1.0"
|
|
rand = "0.8"
|
|
|
|
[features]
|
|
default = ["monitoring"]
|
|
monitoring = ["serde", "serde_json"]
|
|
parallel = ["rayon"]
|
|
ffi = []
|
|
|
|
[[bench]]
|
|
name = "mincut_bench"
|
|
harness = false
|
|
|
|
[lib]
|
|
crate-type = ["lib", "cdylib", "staticlib"]
|
|
```
|
|
|
|
### 1.2 API Integration Points
|
|
|
|
**Add to `ruvector-graph`**:
|
|
```rust
|
|
// In ruvector-graph/src/algorithms/mod.rs
|
|
#[cfg(feature = "mincut")]
|
|
pub mod mincut {
|
|
pub use ruvector_mincut::*;
|
|
}
|
|
|
|
// Extension trait for Graph
|
|
#[cfg(feature = "mincut")]
|
|
impl Graph {
|
|
/// Compute dynamic minimum cut
|
|
pub fn dynamic_mincut(&self) -> DynamicMinCut {
|
|
DynamicMinCut::from_graph(self, MinCutConfig::default())
|
|
}
|
|
|
|
/// Compute minimum cut value (static)
|
|
pub fn min_cut_value(&self) -> usize {
|
|
let mincut = self.dynamic_mincut();
|
|
mincut.min_cut_value()
|
|
}
|
|
}
|
|
```
|
|
|
|
### 1.3 Feature Flag Configuration
|
|
|
|
```toml
|
|
# In ruvector-graph/Cargo.toml
|
|
[features]
|
|
mincut = ["ruvector-mincut"]
|
|
|
|
[dependencies]
|
|
ruvector-mincut = { workspace = true, optional = true }
|
|
```
|
|
|
|
## 2. Documentation
|
|
|
|
### 2.1 API Documentation
|
|
|
|
**Create `crates/ruvector-mincut/README.md`**:
|
|
````markdown
|
|
# ruvector-mincut
|
|
|
|
Subpolynomial-time dynamic minimum cut algorithm for real-time graph monitoring.
|
|
|
|
## Features
|
|
|
|
- **Deterministic**: No probabilistic error
|
|
- **Fast**: Subpolynomial amortized update time O(n^{o(1)})
|
|
- **Exact**: For cuts up to 2^{Θ((log n)^{3/4})} edges
|
|
- **Approximate**: (1+ε)-approximate for larger cuts
|
|
- **Real-time**: Hundreds to thousands of updates/second
|
|
|
|
## Quick Start
|
|
|
|
```rust
|
|
use ruvector_mincut::*;
|
|
|
|
// Create dynamic min-cut structure
|
|
let mut mincut = DynamicMinCut::new(MinCutConfig::default());
|
|
|
|
// Insert edges
|
|
mincut.insert_edge(0, 1).unwrap();
|
|
mincut.insert_edge(1, 2).unwrap();
|
|
mincut.insert_edge(2, 3).unwrap();
|
|
|
|
// Query minimum cut (O(1))
|
|
let cut_value = mincut.min_cut_value();
|
|
println!("Minimum cut: {}", cut_value);
|
|
|
|
// Get partition
|
|
let result = mincut.min_cut();
|
|
println!("Partition A: {:?}", result.partition_a);
|
|
println!("Partition B: {:?}", result.partition_b);
|
|
```
|
|
|
|
## Performance
|
|
|
|
For graphs with n=10,000 vertices:
|
|
- **Update time**: ~1-5ms per operation
|
|
- **Query time**: ~10ns (O(1))
|
|
- **Throughput**: 1,000-10,000 updates/second
|
|
- **Memory**: ~12MB
|
|
|
|
## Algorithm
|
|
|
|
Based on breakthrough work achieving subpolynomial dynamic minimum cut:
|
|
- Hierarchical tree decomposition with O(log n) height
|
|
- Link-cut trees for efficient connectivity queries
|
|
- Sparsification for (1+ε)-approximate cuts
|
|
- Deterministic expander decomposition
|
|
|
|
## Examples
|
|
|
|
See `examples/` directory for:
|
|
- `basic_usage.rs` - Basic operations
|
|
- `monitoring.rs` - Real-time monitoring
|
|
- `integration.rs` - Integration with ruvector-graph
|
|
|
|
## Benchmarks
|
|
|
|
Run benchmarks:
|
|
```bash
|
|
cargo bench --package ruvector-mincut
|
|
```
|
|
|
|
## References
|
|
|
|
- Abboud et al. "Subpolynomial-Time Dynamic Minimum Cut" (2021+)
|
|
- Thorup. "Near-optimal fully-dynamic graph connectivity" (2000)
|
|
- Sleator & Tarjan. "A data structure for dynamic trees" (1983)
|
|
````
|
|
|
|
### 2.2 Module Documentation
|
|
|
|
**Add to `crates/ruvector-mincut/src/lib.rs`**:
|
|
```rust
|
|
//! # ruvector-mincut
|
|
//!
|
|
//! Dynamic minimum cut algorithm with subpolynomial amortized update time.
|
|
//!
|
|
//! ## Overview
|
|
//!
|
|
//! This crate implements a deterministic, fully-dynamic minimum-cut algorithm
|
|
//! that achieves O(n^{o(1)}) amortized time per edge insertion or deletion.
|
|
//!
|
|
//! ## Core Concepts
|
|
//!
|
|
//! ### Hierarchical Decomposition
|
|
//!
|
|
//! The algorithm maintains a hierarchical tree decomposition of the graph:
|
|
//! - Height: O(log n)
|
|
//! - Each level maintains local minimum cut information
|
|
//! - Updates propagate through O(log n / log log n) levels
|
|
//!
|
|
//! ### Link-Cut Trees
|
|
//!
|
|
//! Used for efficient dynamic connectivity:
|
|
//! - Link: Connect two vertices
|
|
//! - Cut: Disconnect two vertices
|
|
//! - Connected: Check if vertices in same component
|
|
//! - Time: O(log n) amortized
|
|
//!
|
|
//! ### Sparsification
|
|
//!
|
|
//! For (1+ε)-approximate cuts:
|
|
//! - Sample edges with probability ∝ 1/(ε²λ)
|
|
//! - Sparse graph has O(n log n / ε²) edges
|
|
//! - Guarantee: (1-ε)λ ≤ λ_H ≤ (1+ε)λ
|
|
//!
|
|
//! ## Examples
|
|
//!
|
|
//! ### Basic Usage
|
|
//!
|
|
//! ```rust
|
|
//! use ruvector_mincut::*;
|
|
//!
|
|
//! let mut mincut = DynamicMinCut::new(MinCutConfig::default());
|
|
//!
|
|
//! // Build path graph: 0-1-2-3
|
|
//! mincut.insert_edge(0, 1).unwrap();
|
|
//! mincut.insert_edge(1, 2).unwrap();
|
|
//! mincut.insert_edge(2, 3).unwrap();
|
|
//!
|
|
//! assert_eq!(mincut.min_cut_value(), 1);
|
|
//! ```
|
|
//!
|
|
//! ### With Monitoring
|
|
//!
|
|
//! ```rust
|
|
//! use ruvector_mincut::*;
|
|
//!
|
|
//! let config = MinCutConfig {
|
|
//! enable_monitoring: true,
|
|
//! ..Default::default()
|
|
//! };
|
|
//!
|
|
//! let mut mincut = DynamicMinCut::new(config);
|
|
//!
|
|
//! mincut.on_cut_change(Box::new(|old, new| {
|
|
//! println!("Cut changed: {} -> {}", old, new);
|
|
//! }));
|
|
//!
|
|
//! mincut.insert_edge(0, 1).unwrap();
|
|
//!
|
|
//! // View metrics
|
|
//! let metrics = mincut.metrics();
|
|
//! println!("P95 latency: {} ns", metrics.p95_update_time_ns);
|
|
//! ```
|
|
//!
|
|
//! ## Performance Characteristics
|
|
//!
|
|
//! | Operation | Time Complexity | Notes |
|
|
//! |-----------|----------------|-------|
|
|
//! | `insert_edge` | O(n^{o(1)}) amortized | Subpolynomial |
|
|
//! | `delete_edge` | O(n^{o(1)}) amortized | Subpolynomial |
|
|
//! | `min_cut_value` | O(1) | Cached |
|
|
//! | `min_cut` | O(k) | k = cut size |
|
|
//!
|
|
//! ## Safety
|
|
//!
|
|
//! This crate uses minimal `unsafe` code, only in performance-critical
|
|
//! sections that have been carefully verified.
|
|
|
|
#![warn(missing_docs)]
|
|
#![warn(clippy::all)]
|
|
|
|
pub mod core;
|
|
pub mod graph;
|
|
pub mod tree;
|
|
pub mod linkcut;
|
|
pub mod algorithm;
|
|
pub mod sparsify;
|
|
pub mod monitoring;
|
|
pub mod error;
|
|
|
|
pub use core::{DynamicMinCut, MinCutConfig, MinCutResult, MinCutMetrics};
|
|
pub use error::{MinCutError, Result};
|
|
|
|
// Re-export common types
|
|
pub use graph::{DynamicGraph, VertexId, Edge};
|
|
```
|
|
|
|
### 2.3 Examples
|
|
|
|
**Create `examples/basic_usage.rs`**:
|
|
```rust
|
|
use ruvector_mincut::*;
|
|
|
|
fn main() -> Result<()> {
|
|
println!("=== Basic Dynamic Minimum Cut ===\n");
|
|
|
|
// Create dynamic min-cut structure
|
|
let mut mincut = DynamicMinCut::new(MinCutConfig::default());
|
|
|
|
println!("Building path graph: 0-1-2-3");
|
|
mincut.insert_edge(0, 1)?;
|
|
mincut.insert_edge(1, 2)?;
|
|
mincut.insert_edge(2, 3)?;
|
|
|
|
let cut_value = mincut.min_cut_value();
|
|
println!("Minimum cut value: {}\n", cut_value);
|
|
|
|
println!("Building complete graph K4");
|
|
for i in 0..4 {
|
|
for j in i+1..4 {
|
|
mincut.insert_edge(i, j)?;
|
|
}
|
|
}
|
|
|
|
let result = mincut.min_cut();
|
|
println!("Minimum cut value: {}", result.value);
|
|
println!("Partition A: {:?}", result.partition_a);
|
|
println!("Partition B: {:?}", result.partition_b);
|
|
println!("Cut edges: {:?}", result.cut_edges);
|
|
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
**Create `examples/monitoring.rs`**:
|
|
```rust
|
|
use ruvector_mincut::*;
|
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
use std::sync::Arc;
|
|
|
|
fn main() -> Result<()> {
|
|
println!("=== Real-Time Monitoring ===\n");
|
|
|
|
let config = MinCutConfig {
|
|
enable_monitoring: true,
|
|
..Default::default()
|
|
};
|
|
|
|
let mut mincut = DynamicMinCut::new(config);
|
|
|
|
// Track cut changes
|
|
let change_count = Arc::new(AtomicUsize::new(0));
|
|
let count_clone = change_count.clone();
|
|
|
|
mincut.on_cut_change(Box::new(move |old, new| {
|
|
println!("Cut changed: {} -> {}", old, new);
|
|
count_clone.fetch_add(1, Ordering::Relaxed);
|
|
}));
|
|
|
|
// Perform 1000 random updates
|
|
println!("Performing 1000 random updates...");
|
|
use rand::Rng;
|
|
let mut rng = rand::thread_rng();
|
|
|
|
for _ in 0..1000 {
|
|
let u = rng.gen_range(0..100);
|
|
let v = rng.gen_range(0..100);
|
|
|
|
if u != v {
|
|
if rng.gen_bool(0.7) {
|
|
mincut.insert_edge(u, v).ok();
|
|
} else {
|
|
mincut.delete_edge(u, v).ok();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Print metrics
|
|
let metrics = mincut.metrics();
|
|
println!("\n=== Performance Metrics ===");
|
|
println!("Current cut value: {}", metrics.current_cut_value);
|
|
println!("Total updates: {}", metrics.update_count);
|
|
println!("Graph size: {:?}", metrics.graph_size);
|
|
println!("Avg update time: {} μs", metrics.avg_update_time_ns / 1000);
|
|
println!("P95 update time: {} μs", metrics.p95_update_time_ns / 1000);
|
|
println!("P99 update time: {} μs", metrics.p99_update_time_ns / 1000);
|
|
println!("Cut changes: {}", change_count.load(Ordering::Relaxed));
|
|
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
## 3. Testing & Validation
|
|
|
|
### 3.1 Pre-Release Checklist
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# scripts/pre-release-check.sh
|
|
|
|
echo "=== Pre-Release Validation ==="
|
|
|
|
# 1. Build all targets
|
|
echo "Building all targets..."
|
|
cargo build --all-features
|
|
cargo build --no-default-features
|
|
|
|
# 2. Run test suite
|
|
echo "Running tests..."
|
|
cargo test --all-features
|
|
cargo test --no-default-features
|
|
|
|
# 3. Run benchmarks (sanity check)
|
|
echo "Running benchmarks..."
|
|
cargo bench --no-run
|
|
|
|
# 4. Check documentation
|
|
echo "Checking documentation..."
|
|
cargo doc --all-features --no-deps
|
|
|
|
# 5. Run clippy
|
|
echo "Running clippy..."
|
|
cargo clippy --all-features -- -D warnings
|
|
|
|
# 6. Check formatting
|
|
echo "Checking formatting..."
|
|
cargo fmt -- --check
|
|
|
|
# 7. Run property tests
|
|
echo "Running property tests..."
|
|
cargo test --release -- --ignored
|
|
|
|
# 8. Validate examples
|
|
echo "Validating examples..."
|
|
cargo run --example basic_usage
|
|
cargo run --example monitoring
|
|
|
|
echo "=== All checks passed! ==="
|
|
```
|
|
|
|
### 3.2 Performance Validation
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# scripts/validate-performance.sh
|
|
|
|
echo "=== Performance Validation ==="
|
|
|
|
# Run benchmarks and check against targets
|
|
cargo bench --bench mincut_bench -- --save-baseline main
|
|
|
|
# Check that performance meets targets
|
|
# Extract metrics and compare against thresholds
|
|
# (implementation specific to benchmark output format)
|
|
|
|
echo "Performance targets met!"
|
|
```
|
|
|
|
## 4. CI/CD Pipeline
|
|
|
|
### 4.1 GitHub Actions Workflow
|
|
|
|
**Create `.github/workflows/mincut.yml`**:
|
|
```yaml
|
|
name: ruvector-mincut CI
|
|
|
|
on:
|
|
push:
|
|
paths:
|
|
- 'crates/ruvector-mincut/**'
|
|
- '.github/workflows/mincut.yml'
|
|
pull_request:
|
|
paths:
|
|
- 'crates/ruvector-mincut/**'
|
|
|
|
jobs:
|
|
test:
|
|
name: Test
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
matrix:
|
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
rust: [stable, nightly]
|
|
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Install Rust
|
|
uses: actions-rs/toolchain@v1
|
|
with:
|
|
toolchain: ${{ matrix.rust }}
|
|
override: true
|
|
|
|
- name: Cache cargo
|
|
uses: actions/cache@v3
|
|
with:
|
|
path: |
|
|
~/.cargo/bin/
|
|
~/.cargo/registry/index/
|
|
~/.cargo/registry/cache/
|
|
~/.cargo/git/db/
|
|
target/
|
|
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
|
|
- name: Build
|
|
run: cargo build --package ruvector-mincut --all-features
|
|
|
|
- name: Run tests
|
|
run: cargo test --package ruvector-mincut --all-features
|
|
|
|
- name: Run ignored tests (performance)
|
|
run: cargo test --package ruvector-mincut --release -- --ignored
|
|
if: matrix.os == 'ubuntu-latest' && matrix.rust == 'stable'
|
|
|
|
bench:
|
|
name: Benchmark
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Install Rust
|
|
uses: actions-rs/toolchain@v1
|
|
with:
|
|
toolchain: stable
|
|
override: true
|
|
|
|
- name: Run benchmarks
|
|
run: cargo bench --package ruvector-mincut --no-run
|
|
|
|
coverage:
|
|
name: Code Coverage
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Install Rust
|
|
uses: actions-rs/toolchain@v1
|
|
with:
|
|
toolchain: stable
|
|
override: true
|
|
|
|
- name: Install tarpaulin
|
|
run: cargo install cargo-tarpaulin
|
|
|
|
- name: Generate coverage
|
|
run: |
|
|
cargo tarpaulin --package ruvector-mincut \
|
|
--out Lcov --all-features
|
|
|
|
- name: Upload to codecov
|
|
uses: codecov/codecov-action@v3
|
|
with:
|
|
files: ./lcov.info
|
|
|
|
lint:
|
|
name: Lint
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Install Rust
|
|
uses: actions-rs/toolchain@v1
|
|
with:
|
|
toolchain: stable
|
|
components: clippy, rustfmt
|
|
override: true
|
|
|
|
- name: Run clippy
|
|
run: cargo clippy --package ruvector-mincut --all-features -- -D warnings
|
|
|
|
- name: Check formatting
|
|
run: cargo fmt --package ruvector-mincut -- --check
|
|
```
|
|
|
|
## 5. Release Process
|
|
|
|
### 5.1 Version Bump
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# scripts/release.sh
|
|
|
|
VERSION=$1
|
|
|
|
if [ -z "$VERSION" ]; then
|
|
echo "Usage: ./scripts/release.sh <version>"
|
|
exit 1
|
|
fi
|
|
|
|
# Update version in Cargo.toml
|
|
sed -i "s/^version = .*/version = \"$VERSION\"/" crates/ruvector-mincut/Cargo.toml
|
|
|
|
# Update CHANGELOG
|
|
echo "## [$VERSION] - $(date +%Y-%m-%d)" >> CHANGELOG.md
|
|
|
|
# Commit changes
|
|
git add crates/ruvector-mincut/Cargo.toml CHANGELOG.md
|
|
git commit -m "chore(mincut): Release v$VERSION"
|
|
git tag "mincut-v$VERSION"
|
|
|
|
echo "Release v$VERSION prepared"
|
|
echo "Review changes and run: git push && git push --tags"
|
|
```
|
|
|
|
### 5.2 Publishing to crates.io
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# scripts/publish-mincut.sh
|
|
|
|
# Ensure working directory is clean
|
|
if [[ -n $(git status -s) ]]; then
|
|
echo "Error: Working directory is not clean"
|
|
exit 1
|
|
fi
|
|
|
|
# Run pre-release checks
|
|
./scripts/pre-release-check.sh
|
|
|
|
# Publish to crates.io
|
|
cd crates/ruvector-mincut
|
|
cargo publish --dry-run
|
|
read -p "Proceed with publish? (y/n) " -n 1 -r
|
|
echo
|
|
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
source ../../.env && \
|
|
CARGO_REGISTRY_TOKEN=$CRATES_API_KEY cargo publish --no-verify
|
|
echo "Published to crates.io!"
|
|
else
|
|
echo "Publish cancelled"
|
|
fi
|
|
```
|
|
|
|
## 6. Deployment Documentation
|
|
|
|
### 6.1 Installation Guide
|
|
|
|
**Add to `docs/installation.md`**:
|
|
````markdown
|
|
# Installing ruvector-mincut
|
|
|
|
## From crates.io
|
|
|
|
```toml
|
|
[dependencies]
|
|
ruvector-mincut = "0.1"
|
|
```
|
|
|
|
## From source
|
|
|
|
```bash
|
|
git clone https://github.com/ruvnet/ruvector.git
|
|
cd ruvector
|
|
cargo build --package ruvector-mincut --release
|
|
```
|
|
|
|
## Feature Flags
|
|
|
|
```toml
|
|
[dependencies.ruvector-mincut]
|
|
version = "0.1"
|
|
features = ["monitoring", "parallel"]
|
|
```
|
|
|
|
Available features:
|
|
- `monitoring` - Enable performance tracking (default)
|
|
- `parallel` - Parallel update processing
|
|
- `ffi` - C ABI for foreign function interface
|
|
|
|
## Platform Support
|
|
|
|
- **Linux**: x86_64, aarch64
|
|
- **macOS**: x86_64, aarch64 (M1/M2)
|
|
- **Windows**: x86_64
|
|
|
|
## System Requirements
|
|
|
|
- Rust 1.70 or later
|
|
- ~50MB disk space for dependencies
|
|
- ~12MB RAM per 10,000 vertex graph
|
|
````
|
|
|
|
### 6.2 Migration Guide
|
|
|
|
**Create `docs/migration.md`**:
|
|
````markdown
|
|
# Migration Guide
|
|
|
|
## From Static Minimum Cut Algorithms
|
|
|
|
If you're currently using static minimum cut algorithms like Stoer-Wagner:
|
|
|
|
### Before (Static)
|
|
|
|
```rust
|
|
let graph = build_graph();
|
|
let min_cut = stoer_wagner(&graph); // Recompute each time
|
|
```
|
|
|
|
### After (Dynamic)
|
|
|
|
```rust
|
|
let mut mincut = DynamicMinCut::from_graph(&graph, Default::default());
|
|
|
|
// Updates are efficient
|
|
mincut.insert_edge(u, v).unwrap();
|
|
mincut.delete_edge(x, y).unwrap();
|
|
|
|
// Query is O(1)
|
|
let cut_value = mincut.min_cut_value();
|
|
```
|
|
|
|
## Performance Considerations
|
|
|
|
- **Initialization**: O(m log n) one-time cost
|
|
- **Updates**: O(n^{o(1)}) amortized
|
|
- **Queries**: O(1) for value, O(k) for partition
|
|
|
|
When to use:
|
|
- ✅ Frequent updates (>100 per rebuild cost)
|
|
- ✅ Real-time monitoring
|
|
- ✅ Interactive applications
|
|
- ❌ Single static computation (use Stoer-Wagner instead)
|
|
````
|
|
|
|
## 7. Monitoring & Observability
|
|
|
|
### 7.1 Prometheus Exporter
|
|
|
|
**Add monitoring integration**:
|
|
```rust
|
|
// In src/monitoring/export.rs
|
|
#[cfg(feature = "monitoring")]
|
|
pub fn export_prometheus(mincut: &DynamicMinCut) -> String {
|
|
let metrics = mincut.metrics();
|
|
|
|
format!(
|
|
r#"# TYPE ruvector_mincut_value gauge
|
|
ruvector_mincut_value {{}} {}
|
|
|
|
# TYPE ruvector_mincut_updates_total counter
|
|
ruvector_mincut_updates_total {{}} {}
|
|
|
|
# TYPE ruvector_mincut_update_time_ns histogram
|
|
ruvector_mincut_update_time_ns_bucket {{le="1000"}} 0
|
|
ruvector_mincut_update_time_ns_bucket {{le="10000"}} {}
|
|
ruvector_mincut_update_time_ns_bucket {{le="100000"}} {}
|
|
ruvector_mincut_update_time_ns_bucket {{le="+Inf"}} {}
|
|
ruvector_mincut_update_time_ns_sum {}
|
|
ruvector_mincut_update_time_ns_count {}
|
|
"#,
|
|
metrics.current_cut_value,
|
|
metrics.update_count,
|
|
// ... histogram buckets
|
|
metrics.avg_update_time_ns * metrics.update_count,
|
|
metrics.update_count
|
|
)
|
|
}
|
|
```
|
|
|
|
## 8. Final Validation
|
|
|
|
### 8.1 Pre-Release Validation Checklist
|
|
|
|
- [ ] All tests pass on all platforms
|
|
- [ ] Benchmarks meet performance targets
|
|
- [ ] Documentation is complete and accurate
|
|
- [ ] Examples run successfully
|
|
- [ ] No clippy warnings
|
|
- [ ] Code coverage >80%
|
|
- [ ] Performance regression tests pass
|
|
- [ ] Integration with ruvector-graph works
|
|
- [ ] C ABI exports are functional
|
|
- [ ] README is comprehensive
|
|
- [ ] CHANGELOG is updated
|
|
- [ ] License files are present
|
|
|
|
### 8.2 Post-Release Tasks
|
|
|
|
- [ ] Publish to crates.io
|
|
- [ ] Create GitHub release with changelog
|
|
- [ ] Update main README to mention new crate
|
|
- [ ] Announce on relevant forums/channels
|
|
- [ ] Monitor for bug reports
|
|
- [ ] Prepare patch releases if needed
|
|
|
|
## 9. Maintenance Plan
|
|
|
|
### 9.1 Regular Tasks
|
|
|
|
**Weekly**:
|
|
- Review and respond to issues
|
|
- Merge non-breaking PRs
|
|
- Run performance benchmarks
|
|
|
|
**Monthly**:
|
|
- Dependency updates
|
|
- Performance optimization review
|
|
- Documentation improvements
|
|
|
|
**Quarterly**:
|
|
- Major feature releases
|
|
- Breaking API changes (if needed)
|
|
- Comprehensive testing
|
|
|
|
### 9.2 Support Channels
|
|
|
|
- **GitHub Issues**: Bug reports and feature requests
|
|
- **Discussions**: General questions and usage help
|
|
- **Email**: security@ruvector.io for security issues
|
|
|
|
## 10. Success Metrics
|
|
|
|
### 10.1 Technical Metrics
|
|
|
|
- **Performance**: Meets O(n^{o(1)}) target
|
|
- **Correctness**: 100% pass rate on test suite
|
|
- **Coverage**: >80% code coverage
|
|
- **Memory**: <2x graph size overhead
|
|
|
|
### 10.2 Adoption Metrics
|
|
|
|
- **Downloads**: Track crates.io downloads
|
|
- **GitHub Stars**: Community interest
|
|
- **Issues**: Response time <48 hours
|
|
- **PRs**: Review time <1 week
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
This completes the SPARC implementation plan for the subpolynomial-time dynamic minimum cut system. The five phases provide:
|
|
|
|
1. **Specification**: Complete requirements and API design
|
|
2. **Pseudocode**: Detailed algorithms for all operations
|
|
3. **Architecture**: System design and module structure
|
|
4. **Refinement**: Comprehensive TDD test plan
|
|
5. **Completion**: Integration, deployment, and documentation
|
|
|
|
**Next Steps**:
|
|
1. Begin Phase 4 (Refinement) with TDD implementation
|
|
2. Follow the test-first development cycle
|
|
3. Continuously benchmark against performance targets
|
|
4. Integrate with ruvector-graph early and often
|
|
|
|
**Estimated Timeline**: ~20 days for V1.0 release
|