pub struct SingleFileDiskANN {
pub dim: usize,
pub num_vectors: usize,
pub max_degree: usize,
pub fraction_top: f64,
pub fraction_mid: f64,
pub distance_metric: DistanceMetric,
/* private fields */
}
Expand description
Main struct representing a DiskANN index
Fields§
§dim: usize
Dimensionality of vectors in the index
num_vectors: usize
Number of vectors in the index
max_degree: usize
Maximum number of edges per node
fraction_top: f64
Fraction of vectors in top layer
fraction_mid: f64
Fraction of vectors in middle layer
distance_metric: DistanceMetric
Distance metric used by this index
Implementations§
Source§impl SingleFileDiskANN
impl SingleFileDiskANN
Sourcepub fn build_index_singlefile(
num_vectors: usize,
dim: usize,
max_degree: usize,
fraction_top: f64,
fraction_mid: f64,
distance_metric: DistanceMetric,
singlefile_path: &str,
) -> Result<Self, DiskAnnError>
pub fn build_index_singlefile( num_vectors: usize, dim: usize, max_degree: usize, fraction_top: f64, fraction_mid: f64, distance_metric: DistanceMetric, singlefile_path: &str, ) -> Result<Self, DiskAnnError>
Builds a new single-file index with the specified parameters
§Arguments
num_vectors
- Number of vectors to storedim
- Dimensionality of the vectorsmax_degree
- Maximum number of edges per nodefraction_top
- Fraction of vectors in top layerfraction_mid
- Fraction of vectors in middle layerdistance_metric
- Distance metric to usesinglefile_path
- Path where the index file will be created
§Returns
Returns Result<SingleFileDiskANN, DiskAnnError>
Examples found in repository?
examples/demo.rs (lines 17-25)
5fn main() -> Result<(), DiskAnnError> {
6 let singlefile_path = "diskann.db";
7 let num_vectors = 100_000;
8 let dim = 128;
9 let max_degree = 32;
10 let fraction_top = 0.01;
11 let fraction_mid = 0.1;
12 let distance_metric = DistanceMetric::Cosine;
13
14 // Build if missing
15 if !std::path::Path::new(singlefile_path).exists() {
16 println!("Building single-file diskann at {singlefile_path}...");
17 let index = SingleFileDiskANN::build_index_singlefile(
18 num_vectors,
19 dim,
20 max_degree,
21 fraction_top,
22 fraction_mid,
23 distance_metric,
24 singlefile_path,
25 )?;
26 println!("Build done. Index dimension = {}", index.dim);
27 } else {
28 println!("Index file {singlefile_path} already exists, skipping build.");
29 }
30
31 // Open
32 let index = Arc::new(SingleFileDiskANN::open_index_singlefile(singlefile_path)?);
33
34 // Query
35 let query = vec![0.1, 0.2, 0.3 /* ... up to dim */];
36 let k = 10;
37 let beam_width = 64;
38 let neighbors = index.search(&query, k, beam_width);
39 println!("Neighbors for the sample query = {:?}", neighbors);
40
41 Ok(())
42}
More examples
examples/perf_test.rs (lines 24-32)
7fn main() -> Result<(), DiskAnnError> {
8 const NUM_VECTORS: usize = 1_000_000;
9 const DIM: usize = 1536;
10 const MAX_DEGREE: usize = 32;
11 const FRACTION_TOP: f64 = 0.01;
12 const FRACTION_MID: f64 = 0.1;
13 let distance_metric = DistanceMetric::Cosine;
14
15 let singlefile_path = "diskann_parallel.db";
16
17 // Build if missing
18 if !std::path::Path::new(singlefile_path).exists() {
19 println!(
20 "Building single-file index with parallel adjacency + distance={:?}",
21 distance_metric
22 );
23 let start = Instant::now();
24 let _index = SingleFileDiskANN::build_index_singlefile(
25 NUM_VECTORS,
26 DIM,
27 MAX_DEGREE,
28 FRACTION_TOP,
29 FRACTION_MID,
30 distance_metric,
31 singlefile_path,
32 )?;
33 let elapsed = start.elapsed().as_secs_f32();
34 println!("Done building index in {:.2} s", elapsed);
35 } else {
36 println!(
37 "Index file {} already exists, skipping build.",
38 singlefile_path
39 );
40 }
41
42 // open
43 let open_start = Instant::now();
44 let index = Arc::new(SingleFileDiskANN::open_index_singlefile(singlefile_path)?);
45 let open_time = open_start.elapsed().as_secs_f32();
46 println!(
47 "Opened index with {} vectors, dim={}, metric={:?} in {:.2} s",
48 index.num_vectors, index.dim, index.distance_metric, open_time
49 );
50
51 // Create queries
52 let queries = 5;
53 let k = 10;
54 let beam_width = 64;
55
56 // Generate all queries in a batch
57 let mut rng = rand::thread_rng();
58 let mut query_batch: Vec<Vec<f32>> = Vec::with_capacity(queries);
59 for _ in 0..queries {
60 let q: Vec<f32> = (0..index.dim).map(|_| rng.gen()).collect();
61 query_batch.push(q);
62 }
63
64 // Now run queries in parallel
65 let search_start = Instant::now();
66 query_batch.par_iter().enumerate().for_each(|(i, query)| {
67 let neighbors = index.search(query, k, beam_width);
68 println!("Query {i} => top-{k} neighbors = {:?}", neighbors);
69 });
70 let search_time = search_start.elapsed().as_secs_f32();
71 println!("Performed {queries} queries in {:.2} s", search_time);
72
73 Ok(())
74}
Sourcepub fn open_index_singlefile(path: &str) -> Result<Self, DiskAnnError>
pub fn open_index_singlefile(path: &str) -> Result<Self, DiskAnnError>
Opens an existing index file
§Arguments
path
- Path to the index file
§Returns
Returns Result<SingleFileDiskANN, DiskAnnError>
Examples found in repository?
examples/demo.rs (line 32)
5fn main() -> Result<(), DiskAnnError> {
6 let singlefile_path = "diskann.db";
7 let num_vectors = 100_000;
8 let dim = 128;
9 let max_degree = 32;
10 let fraction_top = 0.01;
11 let fraction_mid = 0.1;
12 let distance_metric = DistanceMetric::Cosine;
13
14 // Build if missing
15 if !std::path::Path::new(singlefile_path).exists() {
16 println!("Building single-file diskann at {singlefile_path}...");
17 let index = SingleFileDiskANN::build_index_singlefile(
18 num_vectors,
19 dim,
20 max_degree,
21 fraction_top,
22 fraction_mid,
23 distance_metric,
24 singlefile_path,
25 )?;
26 println!("Build done. Index dimension = {}", index.dim);
27 } else {
28 println!("Index file {singlefile_path} already exists, skipping build.");
29 }
30
31 // Open
32 let index = Arc::new(SingleFileDiskANN::open_index_singlefile(singlefile_path)?);
33
34 // Query
35 let query = vec![0.1, 0.2, 0.3 /* ... up to dim */];
36 let k = 10;
37 let beam_width = 64;
38 let neighbors = index.search(&query, k, beam_width);
39 println!("Neighbors for the sample query = {:?}", neighbors);
40
41 Ok(())
42}
More examples
examples/perf_test.rs (line 44)
7fn main() -> Result<(), DiskAnnError> {
8 const NUM_VECTORS: usize = 1_000_000;
9 const DIM: usize = 1536;
10 const MAX_DEGREE: usize = 32;
11 const FRACTION_TOP: f64 = 0.01;
12 const FRACTION_MID: f64 = 0.1;
13 let distance_metric = DistanceMetric::Cosine;
14
15 let singlefile_path = "diskann_parallel.db";
16
17 // Build if missing
18 if !std::path::Path::new(singlefile_path).exists() {
19 println!(
20 "Building single-file index with parallel adjacency + distance={:?}",
21 distance_metric
22 );
23 let start = Instant::now();
24 let _index = SingleFileDiskANN::build_index_singlefile(
25 NUM_VECTORS,
26 DIM,
27 MAX_DEGREE,
28 FRACTION_TOP,
29 FRACTION_MID,
30 distance_metric,
31 singlefile_path,
32 )?;
33 let elapsed = start.elapsed().as_secs_f32();
34 println!("Done building index in {:.2} s", elapsed);
35 } else {
36 println!(
37 "Index file {} already exists, skipping build.",
38 singlefile_path
39 );
40 }
41
42 // open
43 let open_start = Instant::now();
44 let index = Arc::new(SingleFileDiskANN::open_index_singlefile(singlefile_path)?);
45 let open_time = open_start.elapsed().as_secs_f32();
46 println!(
47 "Opened index with {} vectors, dim={}, metric={:?} in {:.2} s",
48 index.num_vectors, index.dim, index.distance_metric, open_time
49 );
50
51 // Create queries
52 let queries = 5;
53 let k = 10;
54 let beam_width = 64;
55
56 // Generate all queries in a batch
57 let mut rng = rand::thread_rng();
58 let mut query_batch: Vec<Vec<f32>> = Vec::with_capacity(queries);
59 for _ in 0..queries {
60 let q: Vec<f32> = (0..index.dim).map(|_| rng.gen()).collect();
61 query_batch.push(q);
62 }
63
64 // Now run queries in parallel
65 let search_start = Instant::now();
66 query_batch.par_iter().enumerate().for_each(|(i, query)| {
67 let neighbors = index.search(query, k, beam_width);
68 println!("Query {i} => top-{k} neighbors = {:?}", neighbors);
69 });
70 let search_time = search_start.elapsed().as_secs_f32();
71 println!("Performed {queries} queries in {:.2} s", search_time);
72
73 Ok(())
74}
Sourcepub fn search(&self, query: &[f32], k: usize, beam_width: usize) -> Vec<u32>
pub fn search(&self, query: &[f32], k: usize, beam_width: usize) -> Vec<u32>
Searches the index for nearest neighbors
§Arguments
query
- Query vectork
- Number of nearest neighbors to returnbeam_width
- Beam width for the search
§Returns
Returns a vector of node IDs representing the nearest neighbors
Examples found in repository?
examples/demo.rs (line 38)
5fn main() -> Result<(), DiskAnnError> {
6 let singlefile_path = "diskann.db";
7 let num_vectors = 100_000;
8 let dim = 128;
9 let max_degree = 32;
10 let fraction_top = 0.01;
11 let fraction_mid = 0.1;
12 let distance_metric = DistanceMetric::Cosine;
13
14 // Build if missing
15 if !std::path::Path::new(singlefile_path).exists() {
16 println!("Building single-file diskann at {singlefile_path}...");
17 let index = SingleFileDiskANN::build_index_singlefile(
18 num_vectors,
19 dim,
20 max_degree,
21 fraction_top,
22 fraction_mid,
23 distance_metric,
24 singlefile_path,
25 )?;
26 println!("Build done. Index dimension = {}", index.dim);
27 } else {
28 println!("Index file {singlefile_path} already exists, skipping build.");
29 }
30
31 // Open
32 let index = Arc::new(SingleFileDiskANN::open_index_singlefile(singlefile_path)?);
33
34 // Query
35 let query = vec![0.1, 0.2, 0.3 /* ... up to dim */];
36 let k = 10;
37 let beam_width = 64;
38 let neighbors = index.search(&query, k, beam_width);
39 println!("Neighbors for the sample query = {:?}", neighbors);
40
41 Ok(())
42}
More examples
examples/perf_test.rs (line 67)
7fn main() -> Result<(), DiskAnnError> {
8 const NUM_VECTORS: usize = 1_000_000;
9 const DIM: usize = 1536;
10 const MAX_DEGREE: usize = 32;
11 const FRACTION_TOP: f64 = 0.01;
12 const FRACTION_MID: f64 = 0.1;
13 let distance_metric = DistanceMetric::Cosine;
14
15 let singlefile_path = "diskann_parallel.db";
16
17 // Build if missing
18 if !std::path::Path::new(singlefile_path).exists() {
19 println!(
20 "Building single-file index with parallel adjacency + distance={:?}",
21 distance_metric
22 );
23 let start = Instant::now();
24 let _index = SingleFileDiskANN::build_index_singlefile(
25 NUM_VECTORS,
26 DIM,
27 MAX_DEGREE,
28 FRACTION_TOP,
29 FRACTION_MID,
30 distance_metric,
31 singlefile_path,
32 )?;
33 let elapsed = start.elapsed().as_secs_f32();
34 println!("Done building index in {:.2} s", elapsed);
35 } else {
36 println!(
37 "Index file {} already exists, skipping build.",
38 singlefile_path
39 );
40 }
41
42 // open
43 let open_start = Instant::now();
44 let index = Arc::new(SingleFileDiskANN::open_index_singlefile(singlefile_path)?);
45 let open_time = open_start.elapsed().as_secs_f32();
46 println!(
47 "Opened index with {} vectors, dim={}, metric={:?} in {:.2} s",
48 index.num_vectors, index.dim, index.distance_metric, open_time
49 );
50
51 // Create queries
52 let queries = 5;
53 let k = 10;
54 let beam_width = 64;
55
56 // Generate all queries in a batch
57 let mut rng = rand::thread_rng();
58 let mut query_batch: Vec<Vec<f32>> = Vec::with_capacity(queries);
59 for _ in 0..queries {
60 let q: Vec<f32> = (0..index.dim).map(|_| rng.gen()).collect();
61 query_batch.push(q);
62 }
63
64 // Now run queries in parallel
65 let search_start = Instant::now();
66 query_batch.par_iter().enumerate().for_each(|(i, query)| {
67 let neighbors = index.search(query, k, beam_width);
68 println!("Query {i} => top-{k} neighbors = {:?}", neighbors);
69 });
70 let search_time = search_start.elapsed().as_secs_f32();
71 println!("Performed {queries} queries in {:.2} s", search_time);
72
73 Ok(())
74}
Auto Trait Implementations§
impl Freeze for SingleFileDiskANN
impl RefUnwindSafe for SingleFileDiskANN
impl Send for SingleFileDiskANN
impl Sync for SingleFileDiskANN
impl Unpin for SingleFileDiskANN
impl UnwindSafe for SingleFileDiskANN
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more