use ipfrs_network::{
DistanceMetric, LshConfig, NamespaceId, SemanticDht, SemanticDhtConfig, SemanticNamespace,
SemanticQuery,
};
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== IPFRS Semantic DHT Example ===\n");
println!("1. Creating semantic DHT...");
let config = SemanticDhtConfig {
lsh_hash_functions: 8,
lsh_hash_tables: 4,
lsh_bucket_width: 4.0,
max_query_peers: 20,
query_timeout: Duration::from_secs(10),
enable_caching: true,
cache_ttl: Duration::from_secs(300),
max_cache_size: 1000,
top_k: 10,
..Default::default()
};
let semantic_dht = SemanticDht::new(config);
println!(" ✓ Semantic DHT created\n");
println!("2. Registering namespaces...");
let text_namespace = SemanticNamespace {
id: NamespaceId::text(),
dimension: 768,
distance_metric: DistanceMetric::Cosine,
lsh_config: LshConfig::default(),
};
semantic_dht.register_namespace(text_namespace)?;
println!(" ✓ Registered 'text' namespace (768-dim, Cosine)");
let image_namespace = SemanticNamespace {
id: NamespaceId::image(),
dimension: 512,
distance_metric: DistanceMetric::Euclidean,
lsh_config: LshConfig::default(),
};
semantic_dht.register_namespace(image_namespace)?;
println!(" ✓ Registered 'image' namespace (512-dim, Euclidean)");
let custom_namespace = SemanticNamespace {
id: NamespaceId::new("scientific-papers"),
dimension: 1024,
distance_metric: DistanceMetric::DotProduct,
lsh_config: LshConfig {
hash_functions: 12,
num_tables: 6,
bucket_width: 2.0,
},
};
semantic_dht.register_namespace(custom_namespace)?;
println!(" ✓ Registered 'scientific-papers' namespace (1024-dim, DotProduct)\n");
println!("3. Indexing content...");
for i in 0..10 {
let embedding = generate_mock_embedding(768, i as f32 * 0.1);
let cid = cid::Cid::default();
semantic_dht.index_content(cid, embedding, NamespaceId::text())?;
}
println!(" ✓ Indexed 10 text documents");
for i in 0..5 {
let embedding = generate_mock_embedding(512, i as f32 * 0.2);
let cid = cid::Cid::default();
semantic_dht.index_content(cid, embedding, NamespaceId::image())?;
}
println!(" ✓ Indexed 5 images\n");
println!("4. Computing LSH hashes for query embedding...");
let query_embedding = generate_mock_embedding(768, 0.25);
let hashes = semantic_dht.compute_lsh_hashes(&query_embedding, &NamespaceId::text())?;
println!(" Generated {} LSH hashes:", hashes.len());
for (i, hash) in hashes.iter().enumerate() {
let cid = hash.to_cid();
println!(" Table {}: {:?} → {}", i, &hash.bucket[..3], cid);
}
println!();
println!("5. Executing semantic queries...");
let text_query = SemanticQuery {
embedding: query_embedding.clone(),
namespace: NamespaceId::text(),
top_k: 5,
metadata_filter: None,
timeout: Duration::from_secs(5),
};
let results = semantic_dht.query(text_query)?;
println!(" Text query results (top {}):", results.len());
for (i, result) in results.iter().enumerate() {
println!(
" {}. CID: {} | Score: {:.4} | Peer: {}",
i + 1,
result.cid,
result.score,
result.peer
);
}
println!();
let image_query_embedding = generate_mock_embedding(512, 0.3);
let image_query = SemanticQuery {
embedding: image_query_embedding,
namespace: NamespaceId::image(),
top_k: 3,
metadata_filter: None,
timeout: Duration::from_secs(5),
};
let results = semantic_dht.query(image_query)?;
println!(" Image query results (top {}):", results.len());
for (i, result) in results.iter().enumerate() {
println!(
" {}. CID: {} | Score: {:.4}",
i + 1,
result.cid,
result.score
);
}
println!();
println!("6. Testing query caching...");
let query1 = SemanticQuery {
embedding: query_embedding.clone(),
namespace: NamespaceId::text(),
top_k: 5,
metadata_filter: None,
timeout: Duration::from_secs(5),
};
let _ = semantic_dht.query(query1)?;
let query2 = SemanticQuery {
embedding: query_embedding.clone(),
namespace: NamespaceId::text(),
top_k: 5,
metadata_filter: None,
timeout: Duration::from_secs(5),
};
let _ = semantic_dht.query(query2)?;
let stats = semantic_dht.stats();
println!(" Cache hits: {}", stats.cache_hits);
println!(" Cache misses: {}", stats.cache_misses);
println!(
" Cache hit rate: {:.1}%\n",
(stats.cache_hits as f64 / stats.total_queries as f64) * 100.0
);
println!("7. Semantic DHT Statistics:");
println!(" Total queries: {}", stats.total_queries);
println!(" Successful: {}", stats.successful_queries);
println!(" Failed: {}", stats.failed_queries);
println!(" Indexed content: {}", stats.indexed_content);
println!(" Avg query latency: {:.2}ms", stats.avg_query_latency_ms);
println!("\n Queries per namespace:");
for (namespace, count) in &stats.queries_per_namespace {
println!(" - {}: {}", namespace, count);
}
println!();
println!("8. Registered namespaces:");
let namespaces = semantic_dht.list_namespaces();
for ns_id in namespaces {
if let Some(ns) = semantic_dht.get_namespace(&ns_id) {
println!(
" - {} ({}-dim, {:?})",
ns.id.0, ns.dimension, ns.distance_metric
);
}
}
println!("\n=== Example Complete ===");
Ok(())
}
fn generate_mock_embedding(dim: usize, seed: f32) -> Vec<f32> {
(0..dim).map(|i| ((i as f32 + seed) * 0.1).sin()).collect()
}
#[allow(dead_code)]
fn distance_metric_examples() -> Result<(), Box<dyn std::error::Error>> {
let semantic_dht = SemanticDht::new(SemanticDhtConfig::default());
let euclidean_ns = SemanticNamespace {
id: NamespaceId::new("spatial"),
dimension: 128,
distance_metric: DistanceMetric::Euclidean,
lsh_config: LshConfig::default(),
};
semantic_dht.register_namespace(euclidean_ns)?;
let cosine_ns = SemanticNamespace {
id: NamespaceId::text(),
dimension: 768,
distance_metric: DistanceMetric::Cosine,
lsh_config: LshConfig::default(),
};
semantic_dht.register_namespace(cosine_ns)?;
let manhattan_ns = SemanticNamespace {
id: NamespaceId::new("robust"),
dimension: 256,
distance_metric: DistanceMetric::Manhattan,
lsh_config: LshConfig::default(),
};
semantic_dht.register_namespace(manhattan_ns)?;
let dotprod_ns = SemanticNamespace {
id: NamespaceId::new("normalized"),
dimension: 512,
distance_metric: DistanceMetric::DotProduct,
lsh_config: LshConfig::default(),
};
semantic_dht.register_namespace(dotprod_ns)?;
Ok(())
}
#[allow(dead_code)]
fn lsh_configuration_examples() -> Result<(), Box<dyn std::error::Error>> {
let semantic_dht = SemanticDht::new(SemanticDhtConfig::default());
let high_precision = SemanticNamespace {
id: NamespaceId::new("high-precision"),
dimension: 512,
distance_metric: DistanceMetric::Cosine,
lsh_config: LshConfig {
hash_functions: 16, num_tables: 4,
bucket_width: 2.0, },
};
semantic_dht.register_namespace(high_precision)?;
let high_recall = SemanticNamespace {
id: NamespaceId::new("high-recall"),
dimension: 512,
distance_metric: DistanceMetric::Cosine,
lsh_config: LshConfig {
hash_functions: 8,
num_tables: 8, bucket_width: 4.0,
},
};
semantic_dht.register_namespace(high_recall)?;
let fast_search = SemanticNamespace {
id: NamespaceId::new("fast"),
dimension: 512,
distance_metric: DistanceMetric::Cosine,
lsh_config: LshConfig {
hash_functions: 4, num_tables: 2,
bucket_width: 8.0, },
};
semantic_dht.register_namespace(fast_search)?;
Ok(())
}