use netabase_store::NetabaseStore;
use netabase_store::netabase_definition_module;
use netabase_store::traits::batch::{BatchBuilder, Batchable};
use std::time::Instant;
#[netabase_definition_module(AppDefinition, AppKeys)]
pub mod models {
use netabase_store::{NetabaseModel, netabase};
#[derive(
NetabaseModel,
Clone,
Debug,
PartialEq,
bincode::Encode,
bincode::Decode,
serde::Serialize,
serde::Deserialize,
)]
#[netabase(AppDefinition)]
pub struct Product {
#[primary_key]
pub id: u64,
pub name: String,
pub price: f64,
#[secondary_key]
pub category: String,
pub in_stock: bool,
}
#[derive(
NetabaseModel,
Clone,
Debug,
PartialEq,
bincode::Encode,
bincode::Decode,
serde::Serialize,
serde::Deserialize,
)]
#[netabase(AppDefinition)]
pub struct Order {
#[primary_key]
pub order_id: String,
pub customer_id: u64,
pub product_ids: Vec<u64>,
pub total: f64,
}
}
use models::*;
fn main() -> anyhow::Result<()> {
println!("=== Netabase Store: Batch Operations Example ===\n");
let store = NetabaseStore::<AppDefinition, _>::temp()?;
let product_tree = store.open_tree::<Product>();
println!("Example 1: Basic Batch Insert");
println!("-------------------------------");
basic_batch_example(&product_tree)?;
println!("\nExample 2: Performance Comparison");
println!("----------------------------------");
performance_comparison(&store)?;
println!("\nExample 3: Mixed Batch Operations");
println!("----------------------------------");
mixed_batch_operations(&product_tree)?;
println!("\nExample 4: Cross-Model Operations");
println!("----------------------------------");
cross_model_example(&store)?;
println!("✅ All batch operation examples completed successfully!");
println!("\n💡 Backend Compatibility:");
println!(" This example uses Sled, but BOTH sync backends support batch operations:");
println!(" • Sled: Native, persistent (shown here)");
println!(" • Redb: Native, persistent (same API)");
println!("\n For testing: Use temp() methods for fast, isolated tests");
Ok(())
}
fn basic_batch_example(
product_tree: &netabase_store::databases::sled_store::SledStoreTree<'_, AppDefinition, Product>,
) -> anyhow::Result<()> {
let mut batch = product_tree.create_batch()?;
let products = vec![
Product {
id: 1,
name: "Laptop".to_string(),
price: 999.99,
category: "Electronics".to_string(),
in_stock: true,
},
Product {
id: 2,
name: "Mouse".to_string(),
price: 29.99,
category: "Electronics".to_string(),
in_stock: true,
},
Product {
id: 3,
name: "Desk".to_string(),
price: 299.99,
category: "Furniture".to_string(),
in_stock: false,
},
];
for product in products {
batch.put(product)?;
}
batch.commit()?;
let count = product_tree.len();
println!(
"✓ Successfully inserted {} products using batch operation",
count
);
let electronics = product_tree.get_by_secondary_key(ProductSecondaryKeys::Category(
ProductCategorySecondaryKey("Electronics".to_string()),
))?;
println!("✓ Found {} electronics products", electronics.len());
Ok(())
}
fn performance_comparison(
store: &NetabaseStore<
AppDefinition,
netabase_store::databases::sled_store::SledStore<AppDefinition>,
>,
) -> anyhow::Result<()> {
const NUM_ITEMS: u64 = 1000;
let product_tree_individual = store.open_tree::<Product>();
let start = Instant::now();
for i in 0..NUM_ITEMS {
let product = Product {
id: i + 1000, name: format!("Product {}", i),
price: (i as f64) * 1.5,
category: "Test".to_string(),
in_stock: i % 2 == 0,
};
product_tree_individual.put(product)?;
}
let individual_duration = start.elapsed();
println!(
"Individual puts: {} items in {:?}",
NUM_ITEMS, individual_duration
);
let product_tree_batch = store.open_tree::<Product>();
let start = Instant::now();
let mut batch = product_tree_batch.create_batch()?;
for i in 0..NUM_ITEMS {
let product = Product {
id: i + 2000, name: format!("Product {}", i),
price: (i as f64) * 1.5,
category: "Test".to_string(),
in_stock: i % 2 == 0,
};
batch.put(product)?;
}
batch.commit()?;
let batch_duration = start.elapsed();
println!(
"Batch operation: {} items in {:?}",
NUM_ITEMS, batch_duration
);
let speedup = individual_duration.as_micros() as f64 / batch_duration.as_micros() as f64;
println!("✓ Batch operations were {:.2}x faster!", speedup);
Ok(())
}
fn mixed_batch_operations(
product_tree: &netabase_store::databases::sled_store::SledStoreTree<'_, AppDefinition, Product>,
) -> anyhow::Result<()> {
let mut setup_batch = product_tree.create_batch()?;
for i in 10..20 {
let product = Product {
id: i,
name: format!("Temp Product {}", i),
price: (i as f64) * 10.0,
category: "Temporary".to_string(),
in_stock: true,
};
setup_batch.put(product)?;
}
setup_batch.commit()?;
println!("✓ Added 10 temporary products");
let mut mixed_batch = product_tree.create_batch()?;
for i in 10..15 {
let product = Product {
id: i,
name: format!("Updated Product {}", i),
price: (i as f64) * 15.0, category: "Updated".to_string(),
in_stock: false,
};
mixed_batch.put(product)?;
}
for i in 15..20 {
mixed_batch.remove(ProductPrimaryKey(i))?;
}
mixed_batch.commit()?;
println!("✓ Updated 5 products and removed 5 products in one atomic operation");
let updated = product_tree.get_by_secondary_key(ProductSecondaryKeys::Category(
ProductCategorySecondaryKey("Updated".to_string()),
))?;
println!("✓ Found {} updated products", updated.len());
Ok(())
}
fn cross_model_example(
store: &NetabaseStore<
AppDefinition,
netabase_store::databases::sled_store::SledStore<AppDefinition>,
>,
) -> anyhow::Result<()> {
let product_tree = store.open_tree::<Product>();
let order_tree = store.open_tree::<Order>();
let mut product_batch = product_tree.create_batch()?;
let product_ids = vec![100, 101, 102];
for &id in &product_ids {
let product = Product {
id,
name: format!("Product {}", id),
price: (id as f64) * 2.5,
category: "Sale".to_string(),
in_stock: true,
};
product_batch.put(product)?;
}
product_batch.commit()?;
let mut order_batch = order_tree.create_batch()?;
for i in 0..5 {
let order = Order {
order_id: format!("ORD-{:04}", i),
customer_id: i + 1000,
product_ids: product_ids.clone(),
total: 300.0 + (i as f64 * 10.0),
};
order_batch.put(order)?;
}
order_batch.commit()?;
println!("✓ Inserted {} products", product_ids.len());
println!("✓ Inserted 5 orders referencing those products");
println!("✓ All operations completed atomically within their model type");
Ok(())
}