diskann_benchmark_core/build/mod.rs
1/*
2 * Copyright (c) Microsoft Corporation.
3 * Licensed under the MIT license.
4 */
5
6//! # Benchmark Tools for Build Operations
7//!
8//! Implementations integrate with build infrastructure via the [`Build`] trait. This trait
9//! is sufficient to use the [`build`] and [`build_tracked`] functions, which perform parallelized
10//! builds with aggregated results.
11//!
12//! In contrast to search operations, the results of build ([`BuildResults`] and [`BatchResult`])
13//! contain more information about the parallel task on which they were run. Less aggregation happens
14//! automatically because build operations often display variance as the build progresses. For example,
15//! inserts later in the cycle often take longer than those occurring earlier.
16//!
17//! Since builds are often long-running operations, progress reporting is supported via [`build_tracked`] with
18//! the [`Progress`] and [`AsProgress`] traits.
19//!
20//! ## Customization Points
21//!
22//! The main customization point for build operations is the [`Build`] trait itself and its custom output.
23//! This output is collected on a per-batch basis and will be made available in the final [`BuildResults`].
24//!
25//! ## Example
26//!
27//! The example below shows a toy implementation of [`Build`].
28//!
29//! ```rust
30//! use std::{sync::Arc, num::NonZeroUsize};
31//! use diskann_benchmark_core::build;
32//!
33//! /// A simple example implementation of the `Build` trait.
34//! #[derive(Debug)]
35//! struct Example {
36//! /// Implementations are expected to store data internally with the `Build`
37//! /// orchestrating the work distribution.
38//! num_items: usize,
39//! }
40//!
41//! /// Example `Build::Output`.
42//! #[derive(Debug, PartialEq)]
43//! struct Output {
44//! /// The number of items built in this batch.
45//! num_built: usize,
46//! }
47//!
48//! impl Output {
49//! fn new(num_built: usize) -> Self {
50//! Self { num_built }
51//! }
52//! }
53//!
54//! impl build::Build for Example {
55//! type Output = Output;
56//! fn num_data(&self) -> usize {
57//! self.num_items
58//! }
59//!
60//! async fn build(&self, range: std::ops::Range<usize>) -> diskann::ANNResult<Self::Output> {
61//! // Simulate building the items in the given range.
62//! Ok(Output::new(range.len()))
63//! }
64//! }
65//!
66//! // Run the build.
67//! let runtime = diskann_benchmark_core::tokio::runtime(1).unwrap();
68//!
69//! // Run a build with 100 objects, using a sequential insertion with
70//! // a batchsize of 20.
71//! let results = build::build(
72//! Arc::new(Example { num_items: 100 }),
73//! build::Parallelism::sequential(NonZeroUsize::new(20).unwrap()),
74//! &runtime,
75//! ).unwrap();
76//!
77//! assert_eq!(results.output().len(), 5, "expected 5 batches of 20 items");
78//! assert_eq!(results.output().iter().map(|o| o.output.num_built).sum::<usize>(), 100, "expected 100 items built");
79//! ```
80//!
81//! # Built-In Runners
82//!
83//! ## Graph Index
84//!
85//! * [`graph::SingleInsert`] - A builder for inserting items into a [`diskann::graph::DiskANNIndex`]
86//! using [`diskann::graph::DiskANNIndex::insert`].
87//!
88//! * [`graph::MultiInsert`] - A builder for inserting items into a [`diskann::graph::DiskANNIndex`]
89//! using [`diskann::graph::DiskANNIndex::multi_insert`].
90
91mod api;
92pub use api::{
93 AsProgress, BatchResult, Build, BuildResults, Parallelism, Progress, build, build_tracked,
94};
95
96pub mod graph;
97pub mod ids;