diff --git a/bench/benches/uniform/build.rs b/bench/benches/uniform/build.rs index 827d86b..7aa4d52 100644 --- a/bench/benches/uniform/build.rs +++ b/bench/benches/uniform/build.rs @@ -24,7 +24,7 @@ pub fn benchmark(criterion: &mut Criterion) { pub fn build_rindex() -> (Rindex, Vec<(usize, [f64; D])>) { let mut rng = StdRng::seed_from_u64(0); - let mut index = Rindex::new(10, K).expect("Failed to create Rindex"); + let mut index = Rindex::new(K); let mut points = Vec::new(); for _ in 0..NUM_OPERATIONS { let should_delete = rng.gen_bool(DELETION_PROB); diff --git a/demo/src/main.rs b/demo/src/main.rs index 3c62cfb..dc8ec4c 100644 --- a/demo/src/main.rs +++ b/demo/src/main.rs @@ -20,7 +20,7 @@ fn main() { } // Configure the tree - let mut tree = Rindex::new(5, 5).expect("Invalid fanout"); + let mut tree = Rindex::new(5); let mut point_ids = Vec::new(); let deletion_probability = 0.25; // 25% diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 8855dc7..6fcfb71 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -3,7 +3,7 @@ name = "rindex" version = "0.2.1" edition = "2021" rust-version = "1.63" -description = "Rindex: reverse nearest neighbor search index for high-dimensional clustered datasets." +description = "Rindex: dynamic spatial index for efficiently maintaining *k* nearest neighbors graph of multi-dimensional clustered datasets." readme = "README.md" documentation = "https://docs.rs/rindex" homepage = "https://github.com/azizkayumov/rindex" diff --git a/lib/README.md b/lib/README.md index 03c6b88..23d4a4e 100644 --- a/lib/README.md +++ b/lib/README.md @@ -11,9 +11,8 @@ The following example shows how to maintain *k* nearest neighbors using Rindex: use rindex::Rindex; fn main() { - let fanout = 10; let k = 3; // maintain 3 nearest neighbors for each point - let mut rindex = Rindex::new(fanout, k).expect("Failed to create Rindex"); + let mut rindex = Rindex::new(k); // Insert some points let a = rindex.insert([1.0, 1.0]); @@ -62,9 +61,8 @@ The traditional query operations are supported in addition to the reverse neares use rindex::Rindex; fn main() { - let fanout = 10; let k = 3; - let mut rindex = Rindex::new(fanout, k).expect("Failed to create Rindex"); + let mut rindex = Rindex::new(k); let a = rindex.insert([1.0, 1.0]); let b = rindex.insert([2.0, 2.0]); let c = rindex.insert([3.0, 3.0]); diff --git a/lib/src/rindex.rs b/lib/src/rindex.rs index 6a78a03..371019d 100644 --- a/lib/src/rindex.rs +++ b/lib/src/rindex.rs @@ -4,14 +4,15 @@ use std::{collections::BinaryHeap, vec}; use crate::{distance::euclidean, index::Index, node::Node, sphere::Sphere}; use ordered_float::OrderedFloat; +/// Rindex: dynamic spatial index for efficiently maintaining *k* nearest neighbors graph of multi-dimensional clustered datasets. +/// /// # Examples /// /// ``` /// use rindex::Rindex; /// -/// let fanout = 10; /// let k = 3; -/// let mut rindex = Rindex::new(fanout, k).expect("Failed to create Rindex"); +/// let mut rindex = Rindex::new(k); /// /// // Insert some points /// let a = rindex.insert([1.0, 1.0]); @@ -43,21 +44,21 @@ pub struct Rindex { impl Default for Rindex { fn default() -> Self { - Rindex::new(10, 10).expect("Invalid fanout") + Rindex::new(10) } } // Public methods impl Rindex { #[must_use] - pub fn new(fanout: usize, k: usize) -> Option { - if fanout < 4 || k < 1 { + pub fn new_with_params(max_fanout: usize, k: usize) -> Option { + if max_fanout < 4 || k < 1 { return None; } Some(Rindex { - min_fanout: fanout / 2, - max_fanout: fanout, - reinsert_fanout: fanout / 3, + min_fanout: max_fanout / 2, + max_fanout, + reinsert_fanout: max_fanout / 3, reinsert_height: 1, k, root: usize::MAX, @@ -66,6 +67,20 @@ impl Rindex { }) } + #[must_use] + pub fn new(k: usize) -> Self { + Rindex { + min_fanout: 5, + max_fanout: 10, + reinsert_fanout: 3, + reinsert_height: 1, + k, + root: usize::MAX, + index: Index::new(), + num_points: 0, + } + } + /// # Examples /// ``` /// use rindex::Rindex; @@ -202,9 +217,8 @@ impl Rindex { /// ``` /// use rindex::Rindex; /// - /// let fanout = 10; /// let k = 3; - /// let mut rindex = Rindex::new(fanout, k).expect("Failed to create Rindex"); + /// let mut rindex = Rindex::new(k); /// let a = rindex.insert([1.0, 1.0]); /// let b = rindex.insert([2.0, 2.0]); /// let c = rindex.insert([3.0, 3.0]); @@ -242,9 +256,8 @@ impl Rindex { /// ``` /// use rindex::Rindex; /// - /// let fanout = 10; /// let k = 3; - /// let mut rindex = Rindex::new(fanout, k).expect("Failed to create Rindex"); + /// let mut rindex = Rindex::new(k); /// /// // Insert some points /// let a = rindex.insert([1.0, 1.0]); @@ -278,9 +291,8 @@ impl Rindex { /// ``` /// use rindex::Rindex; /// - /// let fanout = 10; /// let k = 3; - /// let mut rindex = Rindex::new(fanout, k).expect("Failed to create Rindex"); + /// let mut rindex = Rindex::new(k); /// /// // Insert some points /// let a = rindex.insert([1.0, 1.0]); @@ -306,7 +318,7 @@ impl Rindex { /// /// let fanout = 4; /// let k = 3; - /// let mut rindex = Rindex::new(fanout, k).expect("Failed to create Rindex"); + /// let mut rindex = Rindex::new_with_params(fanout, k).expect("Failed to create Rindex"); /// /// // Insert some points /// let a = rindex.insert([1.0, 1.0]); @@ -862,7 +874,7 @@ mod tests { fn split() { let fanout = 8; let k = 10; - let mut rindex = Rindex::new(fanout, k).expect("Invalid fanout"); + let mut rindex = Rindex::new_with_params(fanout, k).expect("Invalid fanout"); // Create 9 point nodes, as the fanout of 8 will trigger a split let node_a = rindex.add_slot(Node::point([0.0, 0.0])); @@ -910,7 +922,7 @@ mod tests { fn update() { let fanout = 8; let k = 10; - let mut rindex = Rindex::new(fanout, k).expect("Invalid fanout"); + let mut rindex = Rindex::new_with_params(fanout, k).expect("Invalid fanout"); // The tree should be empty assert_eq!(rindex.height(), 0); @@ -982,7 +994,7 @@ mod tests { fn knn_distances() { let fanout = 5; let k = 5; - let mut rindex = Rindex::new(fanout, k).expect("Invalid fanout"); + let mut rindex = Rindex::new_with_params(fanout, k).expect("Invalid fanout"); // Insert some points let a = rindex.insert([0.0, 1.0]); @@ -1058,9 +1070,8 @@ mod tests { #[test] fn reverse_query() { - let fanout = 5; let k = 5; - let mut rindex = Rindex::new(fanout, k).expect("Invalid fanout"); + let mut rindex = Rindex::new(k); for i in 0..100 { let _ = rindex.insert([i as f64, i as f64]); diff --git a/lib/tests/graph.rs b/lib/tests/graph.rs index da8802c..db5ca01 100644 --- a/lib/tests/graph.rs +++ b/lib/tests/graph.rs @@ -8,7 +8,6 @@ use std::collections::{BinaryHeap, HashMap}; fn test_knn_graph() { let num_ops = 1000; let deletion_probability = 0.2; - let fanout = 10; let k = 5; // Configure the random number generator and the points @@ -16,7 +15,7 @@ fn test_knn_graph() { let mut points = Vec::new(); // Create the rindex - let mut rindex = Rindex::new(fanout, k).expect("Invalid fanout"); + let mut rindex = Rindex::new(k); // Create the brute force neighbors let mut bruteforce = BruteForceNeighbors::new(k); diff --git a/lib/tests/random.rs b/lib/tests/random.rs index a0cbd5f..80998c9 100644 --- a/lib/tests/random.rs +++ b/lib/tests/random.rs @@ -3,6 +3,7 @@ use rindex::Rindex; #[test] fn test_random() { + // Create a new Rindex let mut rindex = Rindex::default(); // We will perform some random insertions and deletions diff --git a/lib/tests/usage.rs b/lib/tests/usage.rs index f81f3bc..d08c4ac 100644 --- a/lib/tests/usage.rs +++ b/lib/tests/usage.rs @@ -3,9 +3,8 @@ use rindex::Rindex; #[allow(unused_variables)] #[test] fn test_main_usage() { - let fanout = 10; let k = 3; // maintain 3 nearest neighbors for each point - let mut rindex = Rindex::new(fanout, k).expect("Failed to create Rindex"); + let mut rindex = Rindex::new(k); // Insert some points let a = rindex.insert([1.0, 1.0]); @@ -38,9 +37,10 @@ fn test_update_operations() { #[allow(unused_variables)] #[test] fn test_query_operations() { - let fanout = 10; let k = 3; - let mut rindex = Rindex::new(fanout, k).expect("Failed to create Rindex"); + let mut rindex = Rindex::new(k); + + // Insert some points let a = rindex.insert([1.0, 1.0]); let b = rindex.insert([2.0, 2.0]); let c = rindex.insert([3.0, 3.0]);