use bytes::Bytes;
use ipfrs_core::Block;
use ipfrs_storage::{
BlockStoreTrait, BloomBlockStore, BloomConfig, CachedBlockStore, MemoryBlockStore, PinManager,
};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
println!("=== IPFRS Storage Simple Demo ===\n");
basic_storage_demo().await?;
caching_demo().await?;
bloom_filter_demo().await?;
pin_management_demo()?;
println!("\n=== Demo completed successfully ===");
Ok(())
}
async fn basic_storage_demo() -> anyhow::Result<()> {
println!("1. Basic Storage Operations");
let store = MemoryBlockStore::new();
let block = Block::new(Bytes::from("Hello, IPFRS!"))?;
let cid = *block.cid();
println!(" - Storing block: {}", cid);
store.put(&block).await?;
let retrieved = store.get(&cid).await?;
assert!(retrieved.is_some());
println!(" - Retrieved block successfully");
let exists = store.has(&cid).await?;
println!(" - Block exists: {}", exists);
Ok(())
}
async fn caching_demo() -> anyhow::Result<()> {
println!("\n2. Caching for Performance");
let base_store = MemoryBlockStore::new();
let cache_size = 10 * 1024 * 1024; let cached_store = CachedBlockStore::new(base_store, cache_size);
let blocks: Vec<Block> = (0..5)
.map(|i| Block::new(Bytes::from(format!("Block {}", i))).unwrap())
.collect();
println!(" - Storing {} blocks", blocks.len());
for block in &blocks {
cached_store.put(block).await?;
}
println!(" - First access (cache miss)");
let _ = cached_store.get(blocks[0].cid()).await?;
println!(" - Second access (cache hit)");
let _ = cached_store.get(blocks[0].cid()).await?;
println!(" - Cache working correctly!");
Ok(())
}
async fn bloom_filter_demo() -> anyhow::Result<()> {
println!("\n3. Bloom Filters for Fast Checks");
let base_store = MemoryBlockStore::new();
let bloom_config = BloomConfig::new(10_000, 0.01); let bloom_store = BloomBlockStore::with_config(base_store, bloom_config);
let blocks: Vec<Block> = (0..10)
.map(|i| Block::new(Bytes::from(format!("Bloom block {}", i))).unwrap())
.collect();
println!(" - Storing {} blocks", blocks.len());
for block in &blocks {
bloom_store.put(block).await?;
}
println!(" - Checking existence with bloom filter");
for block in &blocks {
let exists = bloom_store.has(block.cid()).await?;
assert!(exists);
}
let fake_block = Block::new(Bytes::from("non-existent"))?;
let should_not_exist = bloom_store.has(fake_block.cid()).await?;
println!(
" - Non-existent block check: {} (bloom filter works!)",
should_not_exist
);
Ok(())
}
fn pin_management_demo() -> anyhow::Result<()> {
println!("\n4. Pin Management");
let pin_manager = PinManager::new();
let blocks: Vec<Block> = (0..3)
.map(|i| Block::new(Bytes::from(format!("Pin block {}", i))).unwrap())
.collect();
println!(" - Pinning blocks");
for block in &blocks {
pin_manager.pin(block.cid())?;
}
for block in &blocks {
let is_pinned = pin_manager.is_pinned(block.cid());
println!(" Block {} pinned: {}", block.cid(), is_pinned);
}
pin_manager.unpin(blocks[0].cid())?;
println!(" - Unpinned first block");
let stats = pin_manager.stats();
println!(" - Direct pins: {}", stats.direct_pins);
Ok(())
}