1#![allow(clippy::chunks_exact_to_as_chunks)]
8#![deny(
9 rustdoc::bare_urls,
10 rustdoc::broken_intra_doc_links,
11 rustdoc::invalid_html_tags,
12 rustdoc::private_intra_doc_links
13)]
14
15pub mod compression;
28pub mod directories;
29pub mod dsl;
30pub mod error;
31pub mod index;
32pub mod merge;
33pub(crate) mod observe;
34pub mod query;
35#[cfg(feature = "query-diagnostics")]
36pub mod search_diagnostics;
37pub mod segment;
38pub mod structures;
39pub mod tokenizer;
40
41pub use dsl::{
43 BinaryDenseVectorConfig, Document, Field, FieldDef, FieldEntry, FieldType, FieldValue,
44 IndexDef, IvfRoutingMode, QueryLanguageParser, Schema, SchemaBuilder, SdlParser, parse_sdl,
45 parse_single_index,
46};
47
48pub use structures::{
50 AsyncSSTableReader, BlockPostingList, HorizontalBP128Iterator, HorizontalBP128PostingList,
51 PostingList, PostingListIterator, SSTableValue, TERMINATED, TermInfo,
52};
53
54#[cfg(feature = "native")]
56pub use directories::FsDirectory;
57#[cfg(feature = "http")]
58pub use directories::HttpDirectory;
59#[cfg(feature = "native")]
60pub use directories::MmapDirectory;
61pub use directories::{
62 CachingDirectory, Directory, DirectoryWriter, FileHandle, OwnedBytes, RamDirectory,
63 SliceCacheStats, SliceCachingDirectory,
64};
65
66#[cfg(feature = "native")]
68pub type DefaultDirectory = MmapDirectory;
69
70pub use segment::{AsyncStoreReader, FieldStats, SegmentId, SegmentMeta, SegmentReader};
72#[cfg(any(feature = "native", feature = "wasm"))]
73pub use segment::{SegmentBuilder, SegmentBuilderConfig, SegmentBuilderStats};
74
75pub use query::{
77 BinaryDenseVectorQuery, Bm25Params, BooleanQuery, BoostQuery, MaxScoreExecutor, PhraseQuery,
78 PrefixQuery, Query, RegexQuery, ScoredDoc, Scorer, SearchHit, SearchResponse, SearchResult,
79 TermQuery, TopKCollector, WildcardQuery,
80};
81
82pub use tokenizer::{
84 BoxedTokenizer, Language, LanguageAwareTokenizer, LexOptions, LexTokenizer,
85 MultiLanguageStemmer, RawCiTokenizer, RawTokenizer, Script, SimpleTokenizer, StemmerTokenizer,
86 Token, Tokenizer, TokenizerRegistry, TokenizerSpec, language_code, parse_language,
87 parse_language_opt,
88};
89
90pub use directories::SLICE_CACHE_EXTENSION;
92pub use error::{Error, Result};
93pub use index::Searcher;
94#[cfg(all(feature = "wasm", not(feature = "native")))]
95pub use index::WasmIndexWriter;
96#[cfg(feature = "native")]
97pub use index::{Index, IndexReader, IndexWriter};
98pub use index::{IndexConfig, IndexMetadata, SLICE_CACHE_FILENAME};
99#[cfg(feature = "native")]
100pub use index::{
101 IndexingStats, SchemaConfig, SchemaFieldConfig, create_index_at_path, create_index_from_sdl,
102 index_documents_from_reader, index_json_document, parse_schema,
103};
104
105#[cfg(feature = "native")]
107pub use merge::SegmentManager;
108pub use merge::{MergeCandidate, MergePolicy, NoMergePolicy, SegmentInfo, TieredMergePolicy};
109
110pub type DocId = u32;
111pub type TermFreq = u32;
112pub type Score = f32;
113
114pub fn format_bytes(bytes: u64) -> String {
119 const KIB: u64 = 1024;
120 const MIB: u64 = 1024 * KIB;
121 const GIB: u64 = 1024 * MIB;
122 const TIB: u64 = 1024 * GIB;
123
124 if bytes >= TIB {
125 format!("{:.2} TiB", bytes as f64 / TIB as f64)
126 } else if bytes >= GIB {
127 format!("{:.2} GiB", bytes as f64 / GIB as f64)
128 } else if bytes >= MIB {
129 format!("{:.2} MiB", bytes as f64 / MIB as f64)
130 } else if bytes >= KIB {
131 format!("{:.2} KiB", bytes as f64 / KIB as f64)
132 } else {
133 format!("{bytes} B")
134 }
135}
136
137#[cfg(feature = "native")]
140pub fn default_indexing_threads() -> usize {
141 default_quarter_cpu_threads()
142}
143
144#[cfg(feature = "native")]
146pub fn default_search_threads() -> usize {
147 default_quarter_cpu_threads()
148}
149
150#[cfg(feature = "native")]
153pub fn default_compression_threads() -> usize {
154 default_quarter_cpu_threads()
155}
156
157#[cfg(feature = "native")]
158fn default_quarter_cpu_threads() -> usize {
159 (num_cpus::get() / 4).max(1)
160}
161
162#[cfg(test)]
163mod tests {
164 #[test]
165 fn format_bytes_uses_iec_units() {
166 assert_eq!(super::format_bytes(0), "0 B");
167 assert_eq!(super::format_bytes(1023), "1023 B");
168 assert_eq!(super::format_bytes(1024), "1.00 KiB");
169 assert_eq!(super::format_bytes(1024 * 1024), "1.00 MiB");
170 assert_eq!(super::format_bytes(3 * 1024 * 1024 * 1024), "3.00 GiB");
171 assert_eq!(
172 super::format_bytes(2 * 1024 * 1024 * 1024 * 1024),
173 "2.00 TiB"
174 );
175 }
176
177 #[cfg(feature = "native")]
178 #[test]
179 fn cpu_bound_defaults_share_one_policy() {
180 let expected = (num_cpus::get() / 4).max(1);
181
182 assert_eq!(super::default_indexing_threads(), expected);
183 assert_eq!(super::default_search_threads(), expected);
184 assert_eq!(super::default_compression_threads(), expected);
185 }
186}