pub struct Database { /* private fields */ }Expand description
A Git repository that manages named, mutable collection refs.
Implementations§
Source§impl Database
impl Database
Sourcepub fn validate_collection_name(name: &str) -> Result<()>
pub fn validate_collection_name(name: &str) -> Result<()>
Validates a collection name without opening or creating it.
Sourcepub fn init(path: impl AsRef<Path>) -> Result<Self>
pub fn init(path: impl AsRef<Path>) -> Result<Self>
Initializes a non-bare Git repository and opens it as a database.
Sourcepub fn init_bare(path: impl AsRef<Path>) -> Result<Self>
pub fn init_bare(path: impl AsRef<Path>) -> Result<Self>
Initializes a bare Git repository and opens it as a database.
Examples found in repository?
32fn main() -> git_vdb::Result<()> {
33 let args: Vec<_> = env::args().collect();
34 let count = argument(&args, 1, 1_000);
35 let dimension = argument(&args, 2, 768);
36 let query_count = argument(&args, 3, 100);
37 let clusters = 32.min(count.max(1));
38 let mut rng = SplitMix64(SEED);
39 let centers: Vec<Vec<f32>> = (0..clusters)
40 .map(|_| (0..dimension).map(|_| rng.signed()).collect())
41 .collect();
42 let mut points = Vec::with_capacity(count);
43 for id in 0..count {
44 let center = ¢ers[id % clusters];
45 let vector = center
46 .iter()
47 .map(|component| component + rng.signed() * 0.08)
48 .collect();
49 points.push(Point {
50 id: (id as u64).into(),
51 vector,
52 payload: Default::default(),
53 });
54 }
55 let queries: Vec<Vec<f32>> = (0..query_count)
56 .map(|index| {
57 centers[index % clusters]
58 .iter()
59 .map(|component| component + rng.signed() * 0.04)
60 .collect()
61 })
62 .collect();
63
64 let temp = tempfile::TempDir::new().expect("temporary benchmark repository");
65 let db = Database::init_bare(temp.path())?;
66 let config = CollectionConfig {
67 dimension,
68 ..CollectionConfig::default()
69 };
70 let collection = db.create_collection("benchmark", config.clone())?;
71 let started = Instant::now();
72 let root = collection.upsert(points)?.root;
73 let build_ms = started.elapsed().as_millis();
74
75 let exact_started = Instant::now();
76 let mut exact = Vec::new();
77 for vector in &queries {
78 exact.push(collection.query(Query {
79 vector: vector.clone(),
80 limit: 10,
81 params: QueryParams {
82 exact: Some(true),
83 ..QueryParams::default()
84 },
85 ..Query::default()
86 })?);
87 }
88 let exact_query_ms = exact_started.elapsed().as_millis();
89
90 let approximate_started = Instant::now();
91 let mut approximate = Vec::new();
92 for vector in &queries {
93 approximate.push(collection.query(Query {
94 vector: vector.clone(),
95 limit: 10,
96 params: QueryParams {
97 exact: Some(false),
98 ..QueryParams::default()
99 },
100 ..Query::default()
101 })?);
102 }
103 let approximate_query_ms = approximate_started.elapsed().as_millis();
104
105 let recall = |k: usize| -> f64 {
106 exact
107 .iter()
108 .zip(&approximate)
109 .map(|(oracle, result)| {
110 let wanted: BTreeSet<_> = oracle.points.iter().take(k).map(|p| &p.id).collect();
111 result
112 .points
113 .iter()
114 .take(k)
115 .filter(|p| wanted.contains(&p.id))
116 .count() as f64
117 / k as f64
118 })
119 .sum::<f64>()
120 / query_count.max(1) as f64
121 };
122 let mut fractions: Vec<_> = approximate
123 .iter()
124 .map(|result| result.stats.vectors_scored as f64 / count.max(1) as f64)
125 .collect();
126 fractions.sort_by(f64::total_cmp);
127 let median_scored_fraction = fractions.get(fractions.len() / 2).copied().unwrap_or(0.0);
128 let count_objects = Command::new("git")
129 .arg("--git-dir")
130 .arg(temp.path())
131 .args(["count-objects", "-v"])
132 .output()
133 .expect("git count-objects");
134 let count_objects = String::from_utf8(count_objects.stdout).expect("UTF-8 Git output");
135 let metric = |name: &str| {
136 count_objects
137 .lines()
138 .find_map(|line| line.strip_prefix(&format!("{name}: ")))
139 .and_then(|value| value.parse().ok())
140 .unwrap_or(0)
141 };
142 let revision = Command::new("git")
143 .args(["rev-parse", "--short=12", "HEAD"])
144 .output()
145 .ok()
146 .filter(|output| output.status.success())
147 .and_then(|output| String::from_utf8(output.stdout).ok())
148 .map(|value| value.trim().to_owned())
149 .unwrap_or_else(|| "uncommitted".into());
150 println!(
151 "{}",
152 serde_json::to_string_pretty(&Report {
153 seed: SEED,
154 points: count,
155 dimension,
156 queries: query_count,
157 clusters,
158 index: config.index,
159 root: root.0,
160 build_ms,
161 exact_query_ms,
162 approximate_query_ms,
163 recall_at_1: recall(1),
164 recall_at_5: recall(5),
165 recall_at_10: recall(10),
166 median_scored_fraction,
167 loose_objects: metric("count"),
168 loose_kib: metric("size"),
169 revision,
170 target: format!("{}-{}", env::consts::OS, env::consts::ARCH),
171 })?
172 );
173 Ok(())
174}More examples
28fn main() -> Result<(), Box<dyn std::error::Error>> {
29 let mut args = env::args_os().skip(1);
30 let input = args.next().ok_or("usage: runner INPUT.json OUTPUT.json")?;
31 let output = args.next().ok_or("usage: runner INPUT.json OUTPUT.json")?;
32 if args.next().is_some() {
33 return Err("usage: runner INPUT.json OUTPUT.json".into());
34 }
35 let spec: RunSpec = serde_json::from_slice(&fs::read(input)?)?;
36 if spec.schema_version != 1 {
37 return Err(format!("unsupported harness schema version {}", spec.schema_version).into());
38 }
39 let vectors = read_vectors(&spec.points_path, spec.point_count, spec.dimension)?;
40 let queries = read_vectors(&spec.queries_path, spec.query_count, spec.dimension)?;
41 let points = make_points(&vectors);
42 let maximum_k = *spec.k.iter().max().ok_or("k must not be empty")?;
43 let config = CollectionConfig {
44 dimension: spec.dimension,
45 ..CollectionConfig::default()
46 };
47
48 let setup_started = Instant::now();
49 let core_dir = tempfile::TempDir::new()?;
50 let engine = SnapshotEngine::init(core_dir.path())?;
51 let setup_us = micros(setup_started);
52 let build_started = Instant::now();
53 let snapshot = engine.build(config.clone(), points.clone())?;
54 let build_us = micros(build_started);
55 let baseline_on_disk_bytes = directory_bytes(core_dir.path())?;
56
57 let (exact_query_us, exact_results, exact_vectors_scored) =
58 query_all(&snapshot, &queries, maximum_k, true, None)?;
59 let (approximate_query_us, approximate_results, approximate_vectors_scored) =
60 query_all(&snapshot, &queries, maximum_k, false, None)?;
61 let snapshot_throughput = json!({
62 "exact": query_snapshot_throughput(
63 &snapshot,
64 &queries,
65 maximum_k,
66 true,
67 &spec.concurrency,
68 )?,
69 "approximate": query_snapshot_throughput(
70 &snapshot,
71 &queries,
72 maximum_k,
73 false,
74 &spec.concurrency,
75 )?,
76 });
77
78 let mut filtered = Map::new();
79 for selectivity in &spec.filter_selectivities {
80 let filter = selectivity_filter(*selectivity);
81 let (exact_us, exact, exact_scored) =
82 query_all(&snapshot, &queries, maximum_k, true, Some(filter.clone()))?;
83 let (approximate_us, approximate, approximate_scored) =
84 query_all(&snapshot, &queries, maximum_k, false, Some(filter))?;
85 filtered.insert(
86 selectivity.to_string(),
87 json!({
88 "exact_query_us": exact_us,
89 "approximate_query_us": approximate_us,
90 "exact_results": exact,
91 "approximate_results": approximate,
92 "exact_vectors_scored": exact_scored,
93 "approximate_vectors_scored": approximate_scored,
94 }),
95 );
96 }
97
98 let mut mutations = Map::new();
99 for fraction in &spec.mutation_fractions {
100 let count = fraction_count(spec.point_count, *fraction);
101 let changed = changed_points(&points[..count]);
102 let upsert_started = Instant::now();
103 let upserted = engine.apply(
104 snapshot.root(),
105 changed.into_iter().map(SnapshotMutation::upsert).collect(),
106 )?;
107 let upsert_us = micros(upsert_started);
108 let delete_started = Instant::now();
109 let deleted = engine.apply(
110 snapshot.root(),
111 vec![SnapshotMutation::delete_ids(
112 (0..count).map(|id| PointId::from(id as u64)),
113 )],
114 )?;
115 let delete_us = micros(delete_started);
116 mutations.insert(
117 fraction.to_string(),
118 json!({
119 "points": count,
120 "upsert_us": upsert_us,
121 "delete_us": delete_us,
122 "upsert_root": upserted.root(),
123 "delete_root": deleted.root(),
124 }),
125 );
126 }
127
128 let adapter_setup_started = Instant::now();
129 let adapter_dir = tempfile::TempDir::new()?;
130 let database = Database::init_bare(adapter_dir.path())?;
131 let collection = database.create_collection("benchmark", config)?;
132 let adapter_setup_us = micros(adapter_setup_started);
133 let adapter_build_started = Instant::now();
134 let adapter_root = collection.upsert(points)?.root;
135 let adapter_build_us = micros(adapter_build_started);
136 if adapter_root != snapshot.root() {
137 return Err("snapshot-core and named-adapter roots differ".into());
138 }
139 query_collection_all(&collection, &queries[..1], maximum_k, true, None)?;
140 query_collection_all(&collection, &queries[..1], maximum_k, false, None)?;
141 let (adapter_exact_query_us, adapter_exact_results, adapter_exact_vectors_scored) =
142 query_collection_all(&collection, &queries, maximum_k, true, None)?;
143 let (
144 adapter_approximate_query_us,
145 adapter_approximate_results,
146 adapter_approximate_vectors_scored,
147 ) = query_collection_all(&collection, &queries, maximum_k, false, None)?;
148 let adapter_throughput = json!({
149 "exact": query_collection_throughput(
150 &collection,
151 &queries,
152 maximum_k,
153 true,
154 &spec.concurrency,
155 )?,
156 "approximate": query_collection_throughput(
157 &collection,
158 &queries,
159 maximum_k,
160 false,
161 &spec.concurrency,
162 )?,
163 });
164 let historical_started = Instant::now();
165 let historical = collection.at(&adapter_root)?;
166 let historical_count = historical.count(None)?.count;
167 let historical_read_us = micros(historical_started);
168
169 let report = json!({
170 "schema_version": 1,
171 "engine": "git-vdb",
172 "case_name": spec.case_name,
173 "point_count": spec.point_count,
174 "dimension": spec.dimension,
175 "query_count": spec.query_count,
176 "k": spec.k,
177 "root": snapshot.root(),
178 "setup_us": setup_us,
179 "snapshot_core": {
180 "build_us": build_us,
181 "exact_query_us": exact_query_us,
182 "approximate_query_us": approximate_query_us,
183 "exact_results": exact_results,
184 "approximate_results": approximate_results,
185 "exact_vectors_scored": exact_vectors_scored,
186 "approximate_vectors_scored": approximate_vectors_scored,
187 "throughput": snapshot_throughput,
188 "filtered": filtered,
189 "mutations": mutations,
190 "on_disk_bytes": baseline_on_disk_bytes,
191 },
192 "named_adapter": {
193 "setup_us": adapter_setup_us,
194 "build_us": adapter_build_us,
195 "exact_query_us": adapter_exact_query_us,
196 "approximate_query_us": adapter_approximate_query_us,
197 "exact_results": adapter_exact_results,
198 "approximate_results": adapter_approximate_results,
199 "exact_vectors_scored": adapter_exact_vectors_scored,
200 "approximate_vectors_scored": adapter_approximate_vectors_scored,
201 "throughput": adapter_throughput,
202 "historical_read_us": historical_read_us,
203 "historical_count": historical_count,
204 "on_disk_bytes": directory_bytes(adapter_dir.path())?,
205 }
206 });
207 fs::write(output, serde_json::to_vec_pretty(&report)?)?;
208 Ok(())
209}Sourcepub fn init_with_options(path: impl AsRef<Path>, bare: bool) -> Result<Self>
pub fn init_with_options(path: impl AsRef<Path>, bare: bool) -> Result<Self>
Initializes either a bare or non-bare Git repository.
Sourcepub fn open(path: impl AsRef<Path>) -> Result<Self>
pub fn open(path: impl AsRef<Path>) -> Result<Self>
Opens an existing bare or non-bare Git repository.
Sourcepub fn create_collection(
&self,
name: impl AsRef<str>,
config: CollectionConfig,
) -> Result<Collection>
pub fn create_collection( &self, name: impl AsRef<str>, config: CollectionConfig, ) -> Result<Collection>
Creates an empty named collection with canonical configuration.
The method writes the initial immutable root and commit, then creates the
collection ref. It returns Error::CollectionExists when the name is
already present.
Examples found in repository?
32fn main() -> git_vdb::Result<()> {
33 let args: Vec<_> = env::args().collect();
34 let count = argument(&args, 1, 1_000);
35 let dimension = argument(&args, 2, 768);
36 let query_count = argument(&args, 3, 100);
37 let clusters = 32.min(count.max(1));
38 let mut rng = SplitMix64(SEED);
39 let centers: Vec<Vec<f32>> = (0..clusters)
40 .map(|_| (0..dimension).map(|_| rng.signed()).collect())
41 .collect();
42 let mut points = Vec::with_capacity(count);
43 for id in 0..count {
44 let center = ¢ers[id % clusters];
45 let vector = center
46 .iter()
47 .map(|component| component + rng.signed() * 0.08)
48 .collect();
49 points.push(Point {
50 id: (id as u64).into(),
51 vector,
52 payload: Default::default(),
53 });
54 }
55 let queries: Vec<Vec<f32>> = (0..query_count)
56 .map(|index| {
57 centers[index % clusters]
58 .iter()
59 .map(|component| component + rng.signed() * 0.04)
60 .collect()
61 })
62 .collect();
63
64 let temp = tempfile::TempDir::new().expect("temporary benchmark repository");
65 let db = Database::init_bare(temp.path())?;
66 let config = CollectionConfig {
67 dimension,
68 ..CollectionConfig::default()
69 };
70 let collection = db.create_collection("benchmark", config.clone())?;
71 let started = Instant::now();
72 let root = collection.upsert(points)?.root;
73 let build_ms = started.elapsed().as_millis();
74
75 let exact_started = Instant::now();
76 let mut exact = Vec::new();
77 for vector in &queries {
78 exact.push(collection.query(Query {
79 vector: vector.clone(),
80 limit: 10,
81 params: QueryParams {
82 exact: Some(true),
83 ..QueryParams::default()
84 },
85 ..Query::default()
86 })?);
87 }
88 let exact_query_ms = exact_started.elapsed().as_millis();
89
90 let approximate_started = Instant::now();
91 let mut approximate = Vec::new();
92 for vector in &queries {
93 approximate.push(collection.query(Query {
94 vector: vector.clone(),
95 limit: 10,
96 params: QueryParams {
97 exact: Some(false),
98 ..QueryParams::default()
99 },
100 ..Query::default()
101 })?);
102 }
103 let approximate_query_ms = approximate_started.elapsed().as_millis();
104
105 let recall = |k: usize| -> f64 {
106 exact
107 .iter()
108 .zip(&approximate)
109 .map(|(oracle, result)| {
110 let wanted: BTreeSet<_> = oracle.points.iter().take(k).map(|p| &p.id).collect();
111 result
112 .points
113 .iter()
114 .take(k)
115 .filter(|p| wanted.contains(&p.id))
116 .count() as f64
117 / k as f64
118 })
119 .sum::<f64>()
120 / query_count.max(1) as f64
121 };
122 let mut fractions: Vec<_> = approximate
123 .iter()
124 .map(|result| result.stats.vectors_scored as f64 / count.max(1) as f64)
125 .collect();
126 fractions.sort_by(f64::total_cmp);
127 let median_scored_fraction = fractions.get(fractions.len() / 2).copied().unwrap_or(0.0);
128 let count_objects = Command::new("git")
129 .arg("--git-dir")
130 .arg(temp.path())
131 .args(["count-objects", "-v"])
132 .output()
133 .expect("git count-objects");
134 let count_objects = String::from_utf8(count_objects.stdout).expect("UTF-8 Git output");
135 let metric = |name: &str| {
136 count_objects
137 .lines()
138 .find_map(|line| line.strip_prefix(&format!("{name}: ")))
139 .and_then(|value| value.parse().ok())
140 .unwrap_or(0)
141 };
142 let revision = Command::new("git")
143 .args(["rev-parse", "--short=12", "HEAD"])
144 .output()
145 .ok()
146 .filter(|output| output.status.success())
147 .and_then(|output| String::from_utf8(output.stdout).ok())
148 .map(|value| value.trim().to_owned())
149 .unwrap_or_else(|| "uncommitted".into());
150 println!(
151 "{}",
152 serde_json::to_string_pretty(&Report {
153 seed: SEED,
154 points: count,
155 dimension,
156 queries: query_count,
157 clusters,
158 index: config.index,
159 root: root.0,
160 build_ms,
161 exact_query_ms,
162 approximate_query_ms,
163 recall_at_1: recall(1),
164 recall_at_5: recall(5),
165 recall_at_10: recall(10),
166 median_scored_fraction,
167 loose_objects: metric("count"),
168 loose_kib: metric("size"),
169 revision,
170 target: format!("{}-{}", env::consts::OS, env::consts::ARCH),
171 })?
172 );
173 Ok(())
174}More examples
28fn main() -> Result<(), Box<dyn std::error::Error>> {
29 let mut args = env::args_os().skip(1);
30 let input = args.next().ok_or("usage: runner INPUT.json OUTPUT.json")?;
31 let output = args.next().ok_or("usage: runner INPUT.json OUTPUT.json")?;
32 if args.next().is_some() {
33 return Err("usage: runner INPUT.json OUTPUT.json".into());
34 }
35 let spec: RunSpec = serde_json::from_slice(&fs::read(input)?)?;
36 if spec.schema_version != 1 {
37 return Err(format!("unsupported harness schema version {}", spec.schema_version).into());
38 }
39 let vectors = read_vectors(&spec.points_path, spec.point_count, spec.dimension)?;
40 let queries = read_vectors(&spec.queries_path, spec.query_count, spec.dimension)?;
41 let points = make_points(&vectors);
42 let maximum_k = *spec.k.iter().max().ok_or("k must not be empty")?;
43 let config = CollectionConfig {
44 dimension: spec.dimension,
45 ..CollectionConfig::default()
46 };
47
48 let setup_started = Instant::now();
49 let core_dir = tempfile::TempDir::new()?;
50 let engine = SnapshotEngine::init(core_dir.path())?;
51 let setup_us = micros(setup_started);
52 let build_started = Instant::now();
53 let snapshot = engine.build(config.clone(), points.clone())?;
54 let build_us = micros(build_started);
55 let baseline_on_disk_bytes = directory_bytes(core_dir.path())?;
56
57 let (exact_query_us, exact_results, exact_vectors_scored) =
58 query_all(&snapshot, &queries, maximum_k, true, None)?;
59 let (approximate_query_us, approximate_results, approximate_vectors_scored) =
60 query_all(&snapshot, &queries, maximum_k, false, None)?;
61 let snapshot_throughput = json!({
62 "exact": query_snapshot_throughput(
63 &snapshot,
64 &queries,
65 maximum_k,
66 true,
67 &spec.concurrency,
68 )?,
69 "approximate": query_snapshot_throughput(
70 &snapshot,
71 &queries,
72 maximum_k,
73 false,
74 &spec.concurrency,
75 )?,
76 });
77
78 let mut filtered = Map::new();
79 for selectivity in &spec.filter_selectivities {
80 let filter = selectivity_filter(*selectivity);
81 let (exact_us, exact, exact_scored) =
82 query_all(&snapshot, &queries, maximum_k, true, Some(filter.clone()))?;
83 let (approximate_us, approximate, approximate_scored) =
84 query_all(&snapshot, &queries, maximum_k, false, Some(filter))?;
85 filtered.insert(
86 selectivity.to_string(),
87 json!({
88 "exact_query_us": exact_us,
89 "approximate_query_us": approximate_us,
90 "exact_results": exact,
91 "approximate_results": approximate,
92 "exact_vectors_scored": exact_scored,
93 "approximate_vectors_scored": approximate_scored,
94 }),
95 );
96 }
97
98 let mut mutations = Map::new();
99 for fraction in &spec.mutation_fractions {
100 let count = fraction_count(spec.point_count, *fraction);
101 let changed = changed_points(&points[..count]);
102 let upsert_started = Instant::now();
103 let upserted = engine.apply(
104 snapshot.root(),
105 changed.into_iter().map(SnapshotMutation::upsert).collect(),
106 )?;
107 let upsert_us = micros(upsert_started);
108 let delete_started = Instant::now();
109 let deleted = engine.apply(
110 snapshot.root(),
111 vec![SnapshotMutation::delete_ids(
112 (0..count).map(|id| PointId::from(id as u64)),
113 )],
114 )?;
115 let delete_us = micros(delete_started);
116 mutations.insert(
117 fraction.to_string(),
118 json!({
119 "points": count,
120 "upsert_us": upsert_us,
121 "delete_us": delete_us,
122 "upsert_root": upserted.root(),
123 "delete_root": deleted.root(),
124 }),
125 );
126 }
127
128 let adapter_setup_started = Instant::now();
129 let adapter_dir = tempfile::TempDir::new()?;
130 let database = Database::init_bare(adapter_dir.path())?;
131 let collection = database.create_collection("benchmark", config)?;
132 let adapter_setup_us = micros(adapter_setup_started);
133 let adapter_build_started = Instant::now();
134 let adapter_root = collection.upsert(points)?.root;
135 let adapter_build_us = micros(adapter_build_started);
136 if adapter_root != snapshot.root() {
137 return Err("snapshot-core and named-adapter roots differ".into());
138 }
139 query_collection_all(&collection, &queries[..1], maximum_k, true, None)?;
140 query_collection_all(&collection, &queries[..1], maximum_k, false, None)?;
141 let (adapter_exact_query_us, adapter_exact_results, adapter_exact_vectors_scored) =
142 query_collection_all(&collection, &queries, maximum_k, true, None)?;
143 let (
144 adapter_approximate_query_us,
145 adapter_approximate_results,
146 adapter_approximate_vectors_scored,
147 ) = query_collection_all(&collection, &queries, maximum_k, false, None)?;
148 let adapter_throughput = json!({
149 "exact": query_collection_throughput(
150 &collection,
151 &queries,
152 maximum_k,
153 true,
154 &spec.concurrency,
155 )?,
156 "approximate": query_collection_throughput(
157 &collection,
158 &queries,
159 maximum_k,
160 false,
161 &spec.concurrency,
162 )?,
163 });
164 let historical_started = Instant::now();
165 let historical = collection.at(&adapter_root)?;
166 let historical_count = historical.count(None)?.count;
167 let historical_read_us = micros(historical_started);
168
169 let report = json!({
170 "schema_version": 1,
171 "engine": "git-vdb",
172 "case_name": spec.case_name,
173 "point_count": spec.point_count,
174 "dimension": spec.dimension,
175 "query_count": spec.query_count,
176 "k": spec.k,
177 "root": snapshot.root(),
178 "setup_us": setup_us,
179 "snapshot_core": {
180 "build_us": build_us,
181 "exact_query_us": exact_query_us,
182 "approximate_query_us": approximate_query_us,
183 "exact_results": exact_results,
184 "approximate_results": approximate_results,
185 "exact_vectors_scored": exact_vectors_scored,
186 "approximate_vectors_scored": approximate_vectors_scored,
187 "throughput": snapshot_throughput,
188 "filtered": filtered,
189 "mutations": mutations,
190 "on_disk_bytes": baseline_on_disk_bytes,
191 },
192 "named_adapter": {
193 "setup_us": adapter_setup_us,
194 "build_us": adapter_build_us,
195 "exact_query_us": adapter_exact_query_us,
196 "approximate_query_us": adapter_approximate_query_us,
197 "exact_results": adapter_exact_results,
198 "approximate_results": adapter_approximate_results,
199 "exact_vectors_scored": adapter_exact_vectors_scored,
200 "approximate_vectors_scored": adapter_approximate_vectors_scored,
201 "throughput": adapter_throughput,
202 "historical_read_us": historical_read_us,
203 "historical_count": historical_count,
204 "on_disk_bytes": directory_bytes(adapter_dir.path())?,
205 }
206 });
207 fs::write(output, serde_json::to_vec_pretty(&report)?)?;
208 Ok(())
209}Sourcepub fn get_or_create_collection(
&self,
name: impl AsRef<str>,
config: CollectionConfig,
) -> Result<Collection>
pub fn get_or_create_collection( &self, name: impl AsRef<str>, config: CollectionConfig, ) -> Result<Collection>
Opens a collection or atomically creates it with the supplied config.
An existing collection with different configuration is rejected.
Sourcepub fn collection(&self, name: impl AsRef<str>) -> Result<Collection>
pub fn collection(&self, name: impl AsRef<str>) -> Result<Collection>
Opens the current mutable view of a named collection.
Sourcepub fn list_collections(&self) -> Result<Vec<String>>
pub fn list_collections(&self) -> Result<Vec<String>>
Returns collection names in ascending byte order.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Database
impl RefUnwindSafe for Database
impl Send for Database
impl Sync for Database
impl Unpin for Database
impl UnsafeUnpin for Database
impl UnwindSafe for Database
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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> ⓘ
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> ⓘ
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