Struct DatabaseInner

Source
pub struct DatabaseInner { /* private fields */ }

Implementations§

Source§

impl DatabaseInner

Source

pub fn file_len(&self) -> Result<u64>

Source

pub fn set_min_len(&self, len: u64) -> Result<()>

Source

pub fn set_min_regions(&self, regions: usize) -> Result<()>

Source

pub fn create_region_if_needed( &self, id: &str, ) -> Result<(usize, Arc<RwLock<Region>>)>

Examples found in repository?
examples/db.rs (line 16)
5fn main() -> Result<()> {
6    let _ = fs::remove_dir_all("vecs");
7
8    let database = Database::open(Path::new("vecs"))?;
9
10    // let seqdb_min_len = PAGE_SIZE * 1_000_000;
11    // let min_regions = 20_000;
12
13    // seqdb.set_min_len(seqdb_min_len)?;
14    // seqdb.set_min_regions(min_regions)?;
15
16    let (region1_i, _) = database.create_region_if_needed("region1")?;
17
18    {
19        let layout = database.layout();
20        assert!(layout.start_to_index().len() == 1);
21        assert!(layout.start_to_index().first_key_value() == Some((&0, &0)));
22        assert!(layout.start_to_hole().is_empty());
23
24        let regions = database.regions();
25        assert!(
26            regions
27                .get_region_index_from_id("region1")
28                .is_some_and(|i| i == region1_i)
29        );
30
31        let region = database.get_region(region1_i.into())?;
32        assert!(region.start() == 0);
33        assert!(region.len() == 0);
34        assert!(region.reserved() == PAGE_SIZE);
35    }
36
37    database.write_all_to_region(region1_i.into(), &[0, 1, 2, 3, 4])?;
38
39    {
40        let region = database.get_region(region1_i.into())?;
41        assert!(region.start() == 0);
42        assert!(region.len() == 5);
43        assert!(region.reserved() == PAGE_SIZE);
44
45        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
46    }
47
48    database.write_all_to_region(region1_i.into(), &[5, 6, 7, 8, 9])?;
49
50    {
51        let region = database.get_region(region1_i.into())?;
52        assert!(region.start() == 0);
53        assert!(region.len() == 10);
54        assert!(region.reserved() == PAGE_SIZE);
55
56        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
57    }
58
59    database.write_all_to_region_at(region1_i.into(), &[1, 2], 0)?;
60
61    {
62        let region = database.get_region(region1_i.into())?;
63        assert!(region.start() == 0);
64        assert!(region.len() == 10);
65        assert!(region.reserved() == PAGE_SIZE);
66
67        assert!(database.mmap()[0..10] == [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]);
68    }
69
70    database.write_all_to_region_at(region1_i.into(), &[10, 11, 12, 13, 14, 15, 16, 17, 18], 4)?;
71
72    {
73        let region = database.get_region(region1_i.into())?;
74        assert!(region.start() == 0);
75        assert!(region.len() == 13);
76        assert!(region.reserved() == PAGE_SIZE);
77
78        assert!(
79            database.mmap()[0..20]
80                == [
81                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0
82                ]
83        );
84    }
85
86    database.write_all_to_region_at(region1_i.into(), &[0, 0, 0, 0, 0, 1], 13)?;
87
88    {
89        let region = database.get_region(region1_i.into())?;
90        assert!(region.start() == 0);
91        assert!(region.len() == 19);
92        assert!(region.reserved() == PAGE_SIZE);
93
94        assert!(
95            database.mmap()[0..20]
96                == [
97                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 1, 0
98                ]
99        );
100    }
101
102    dbg!(1);
103
104    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
105
106    {
107        let region = database.get_region(region1_i.into())?;
108        assert!(region.start() == 0);
109        assert!(region.len() == 8000);
110        assert!(region.reserved() == PAGE_SIZE * 2);
111
112        assert!(database.mmap()[0..8000] == [1; 8000]);
113        assert!(database.mmap()[8000..8001] == [0]);
114    }
115
116    println!("Disk usage - pre sync: {}", database.disk_usage());
117    database.flush()?;
118    println!("Disk usage - post sync: {}", database.disk_usage());
119
120    database.truncate_region(region1_i.into(), 10)?;
121    database.punch_holes()?;
122
123    {
124        let region = database.get_region(region1_i.into())?;
125        assert!(region.start() == 0);
126        assert!(region.len() == 10);
127        assert!(region.reserved() == PAGE_SIZE * 2);
128        // We only punch a hole in whole pages (4096 bytes)
129        // Thus the last byte of the page where the is still data wasn't overwritten when truncating
130        // And the first byte of the punched page was set to 0
131        assert!(database.mmap()[4095..=4096] == [1, 0]);
132    }
133
134    database.flush()?;
135    println!("Disk usage - post trunc: {}", database.disk_usage());
136
137    database.remove_region(region1_i.into())?;
138
139    database.flush()?;
140
141    println!("Disk usage - post remove: {}", database.disk_usage());
142
143    {
144        let regions = database.regions();
145        let index_to_region = regions.index_to_region();
146        assert!(index_to_region.len() == 1);
147        assert!(index_to_region[0].is_none());
148        assert!(regions.id_to_index().is_empty());
149
150        let layout = database.layout();
151        assert!(layout.start_to_index().is_empty());
152        assert!(layout.start_to_hole().len() == 1);
153    }
154
155    let (region1_i, _) = database.create_region_if_needed("region1")?;
156    let (region2_i, _) = database.create_region_if_needed("region2")?;
157    let (region3_i, _) = database.create_region_if_needed("region3")?;
158
159    // dbg!(seqdb.layout());
160
161    {
162        let regions = database.regions();
163        let index_to_region = regions.index_to_region();
164        assert!(index_to_region.len() == 3);
165        let region1 = database.get_region(region1_i.into())?;
166        assert!(region1.start() == 0);
167        assert!(region1.len() == 0);
168        assert!(region1.reserved() == PAGE_SIZE);
169        let region2 = database.get_region(region2_i.into())?;
170        assert!(region2.start() == PAGE_SIZE);
171        assert!(region2.len() == 0);
172        assert!(region2.reserved() == PAGE_SIZE);
173        let region3 = database.get_region(region3_i.into())?;
174        assert!(region3.start() == PAGE_SIZE * 2);
175        assert!(region3.len() == 0);
176        assert!(region3.reserved() == PAGE_SIZE);
177        let id_to_index = regions.id_to_index();
178        assert!(id_to_index.len() == 3);
179        assert!(id_to_index.get("region1") == Some(&0));
180        assert!(id_to_index.get("region2") == Some(&1));
181        assert!(id_to_index.get("region3") == Some(&2));
182
183        let layout = database.layout();
184        let start_to_index = layout.start_to_index();
185        assert!(start_to_index.len() == 3);
186        assert!(start_to_index.get(&0) == Some(&0));
187        assert!(start_to_index.get(&PAGE_SIZE) == Some(&1));
188        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&2));
189        assert!(layout.start_to_hole().is_empty());
190    }
191
192    database.remove_region(region2_i.into())?;
193
194    {
195        let regions = database.regions();
196        let index_to_region = regions.index_to_region();
197        assert!(index_to_region.len() == 3);
198        let region1 = database.get_region(region1_i.into())?;
199        assert!(region1.start() == 0);
200        assert!(region1.len() == 0);
201        assert!(region1.reserved() == PAGE_SIZE);
202        assert!(database.get_region(region2_i.into()).is_err());
203        assert!(
204            index_to_region
205                .get(region2_i)
206                .is_some_and(|opt| opt.is_none())
207        );
208        let region3 = database.get_region(region3_i.into())?;
209        assert!(region3.start() == PAGE_SIZE * 2);
210        assert!(region3.len() == 0);
211        assert!(region3.reserved() == PAGE_SIZE);
212        let id_to_index = regions.id_to_index();
213        assert!(id_to_index.len() == 2);
214        assert!(id_to_index.get("region1") == Some(&0));
215        assert!(id_to_index.get("region2").is_none());
216        assert!(id_to_index.get("region3") == Some(&2));
217
218        let layout = database.layout();
219        let start_to_index = layout.start_to_index();
220        assert!(start_to_index.len() == 2);
221        assert!(start_to_index.get(&0) == Some(&region1_i));
222        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
223        let start_to_hole = layout.start_to_hole();
224        assert!(start_to_hole.len() == 1);
225        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
226
227        drop(regions);
228        drop(layout);
229        assert!(
230            database
231                .remove_region(region2_i.into())
232                .is_ok_and(|o| o.is_none())
233        );
234    }
235
236    let (region2_i, _) = database.create_region_if_needed("region2")?;
237
238    {
239        assert!(region2_i == 1)
240    }
241
242    database.remove_region(region2_i.into())?;
243
244    {
245        let regions = database.regions();
246        let index_to_region = regions.index_to_region();
247        assert!(index_to_region.len() == 3);
248        let region1 = database.get_region(region1_i.into())?;
249        assert!(region1.start() == 0);
250        assert!(region1.len() == 0);
251        assert!(region1.reserved() == PAGE_SIZE);
252        assert!(database.get_region(region2_i.into()).is_err());
253        assert!(
254            index_to_region
255                .get(region2_i)
256                .is_some_and(|opt| opt.is_none())
257        );
258        let region3 = database.get_region(region3_i.into())?;
259        assert!(region3.start() == PAGE_SIZE * 2);
260        assert!(region3.len() == 0);
261        assert!(region3.reserved() == PAGE_SIZE);
262        let id_to_index = regions.id_to_index();
263        assert!(id_to_index.len() == 2);
264        assert!(id_to_index.get("region1") == Some(&0));
265        assert!(id_to_index.get("region2").is_none());
266        assert!(id_to_index.get("region3") == Some(&2));
267
268        let layout = database.layout();
269        let start_to_index = layout.start_to_index();
270        assert!(start_to_index.len() == 2);
271        assert!(start_to_index.get(&0) == Some(&region1_i));
272        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
273        let start_to_hole = layout.start_to_hole();
274        assert!(start_to_hole.len() == 1);
275        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
276
277        drop(regions);
278        drop(layout);
279        assert!(
280            database
281                .remove_region(region2_i.into())
282                .is_ok_and(|o| o.is_none())
283        );
284    }
285
286    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
287
288    {
289        let regions = database.regions();
290        let index_to_region = regions.index_to_region();
291        assert!(index_to_region.len() == 3);
292        let region1 = database.get_region(region1_i.into())?;
293        assert!(region1.start() == 0);
294        assert!(region1.len() == 8000);
295        assert!(region1.reserved() == 2 * PAGE_SIZE);
296        assert!(database.get_region(region2_i.into()).is_err());
297        assert!(
298            index_to_region
299                .get(region2_i)
300                .is_some_and(|opt| opt.is_none())
301        );
302        let region3 = database.get_region(region3_i.into())?;
303        assert!(region3.start() == PAGE_SIZE * 2);
304        assert!(region3.len() == 0);
305        assert!(region3.reserved() == PAGE_SIZE);
306        let id_to_index = regions.id_to_index();
307        assert!(id_to_index.len() == 2);
308        assert!(id_to_index.get("region1") == Some(&0));
309        assert!(id_to_index.get("region2").is_none());
310        assert!(id_to_index.get("region3") == Some(&2));
311
312        let layout = database.layout();
313        let start_to_index = layout.start_to_index();
314        assert!(start_to_index.len() == 2);
315        assert!(start_to_index.get(&0) == Some(&region1_i));
316        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
317        let start_to_hole = layout.start_to_hole();
318        assert!(start_to_hole.is_empty());
319    }
320
321    let (region2_i, _) = database.create_region_if_needed("region2")?;
322
323    {
324        let regions = database.regions();
325        let index_to_region = regions.index_to_region();
326        assert!(index_to_region.len() == 3);
327        let region1 = database.get_region(region1_i.into())?;
328        assert!(region1.start() == 0);
329        assert!(region1.len() == 8000);
330        assert!(region1.reserved() == 2 * PAGE_SIZE);
331        let region2 = database.get_region(region2_i.into())?;
332        assert!(region2.start() == PAGE_SIZE * 3);
333        assert!(region2.len() == 0);
334        assert!(region2.reserved() == PAGE_SIZE);
335        let region3 = database.get_region(region3_i.into())?;
336        assert!(region3.start() == PAGE_SIZE * 2);
337        assert!(region3.len() == 0);
338        assert!(region3.reserved() == PAGE_SIZE);
339        let id_to_index = regions.id_to_index();
340        assert!(id_to_index.len() == 3);
341        assert!(id_to_index.get("region1") == Some(&0));
342        assert!(id_to_index.get("region2") == Some(&1));
343        assert!(id_to_index.get("region3") == Some(&2));
344
345        let layout = database.layout();
346        let start_to_index = layout.start_to_index();
347        assert!(start_to_index.len() == 3);
348        assert!(start_to_index.get(&0) == Some(&region1_i));
349        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
350        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
351        let start_to_hole = layout.start_to_hole();
352        assert!(start_to_hole.is_empty());
353    }
354
355    database.remove_region(region3_i.into())?;
356
357    {
358        let regions = database.regions();
359        let index_to_region = regions.index_to_region();
360        assert!(index_to_region.len() == 3);
361        let region1 = database.get_region(region1_i.into())?;
362        assert!(region1.start() == 0);
363        assert!(region1.len() == 8000);
364        assert!(region1.reserved() == 2 * PAGE_SIZE);
365        let region2 = database.get_region(region2_i.into())?;
366        assert!(region2.start() == PAGE_SIZE * 3);
367        assert!(region2.len() == 0);
368        assert!(region2.reserved() == PAGE_SIZE);
369        assert!(database.get_region(region3_i.into()).is_err());
370        let id_to_index = regions.id_to_index();
371        assert!(id_to_index.len() == 2);
372        assert!(id_to_index.get("region1") == Some(&0));
373        assert!(id_to_index.get("region2") == Some(&1));
374        assert!(id_to_index.get("region3").is_none());
375
376        let layout = database.layout();
377        let start_to_index = layout.start_to_index();
378        assert!(start_to_index.len() == 2);
379        assert!(start_to_index.get(&0) == Some(&region1_i));
380        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
381        let start_to_hole = layout.start_to_hole();
382        assert!(start_to_hole.get(&(PAGE_SIZE * 2)) == Some(&PAGE_SIZE));
383    }
384
385    database.write_all_to_region(region1_i.into(), &[1; 8000])?;
386
387    {
388        let regions = database.regions();
389        let index_to_region = regions.index_to_region();
390        assert!(index_to_region.len() == 3);
391        let region1 = database.get_region(region1_i.into())?;
392        assert!(region1.start() == PAGE_SIZE * 4);
393        assert!(region1.len() == 16_000);
394        assert!(region1.reserved() == 4 * PAGE_SIZE);
395        let region2 = database.get_region(region2_i.into())?;
396        assert!(region2.start() == PAGE_SIZE * 3);
397        assert!(region2.len() == 0);
398        assert!(region2.reserved() == PAGE_SIZE);
399        assert!(database.get_region(region3_i.into()).is_err());
400        let id_to_index = regions.id_to_index();
401        assert!(id_to_index.len() == 2);
402        assert!(id_to_index.get("region1") == Some(&0));
403        assert!(id_to_index.get("region2") == Some(&1));
404        assert!(id_to_index.get("region3").is_none());
405
406        let layout = database.layout();
407        let start_to_index = layout.start_to_index();
408        assert!(start_to_index.len() == 2);
409        assert!(start_to_index.get(&(PAGE_SIZE * 4)) == Some(&region1_i));
410        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
411        let start_to_hole = layout.start_to_hole();
412        assert!(start_to_hole.get(&0) == Some(&(PAGE_SIZE * 3)));
413    }
414
415    database.write_all_to_region(region2_i.into(), &[1; 6000])?;
416
417    let (region4_i, _) = database.create_region_if_needed("region4")?;
418    database.remove_region(region2_i.into())?;
419    database.remove_region(region4_i.into())?;
420
421    let regions = database.regions();
422    dbg!(&regions);
423    let layout = database.layout();
424    dbg!(&layout);
425
426    Ok(())
427}
Source

pub fn get_region( &self, identifier: Identifier, ) -> Result<RwLockReadGuard<'static, Region>>

Examples found in repository?
examples/db.rs (line 31)
5fn main() -> Result<()> {
6    let _ = fs::remove_dir_all("vecs");
7
8    let database = Database::open(Path::new("vecs"))?;
9
10    // let seqdb_min_len = PAGE_SIZE * 1_000_000;
11    // let min_regions = 20_000;
12
13    // seqdb.set_min_len(seqdb_min_len)?;
14    // seqdb.set_min_regions(min_regions)?;
15
16    let (region1_i, _) = database.create_region_if_needed("region1")?;
17
18    {
19        let layout = database.layout();
20        assert!(layout.start_to_index().len() == 1);
21        assert!(layout.start_to_index().first_key_value() == Some((&0, &0)));
22        assert!(layout.start_to_hole().is_empty());
23
24        let regions = database.regions();
25        assert!(
26            regions
27                .get_region_index_from_id("region1")
28                .is_some_and(|i| i == region1_i)
29        );
30
31        let region = database.get_region(region1_i.into())?;
32        assert!(region.start() == 0);
33        assert!(region.len() == 0);
34        assert!(region.reserved() == PAGE_SIZE);
35    }
36
37    database.write_all_to_region(region1_i.into(), &[0, 1, 2, 3, 4])?;
38
39    {
40        let region = database.get_region(region1_i.into())?;
41        assert!(region.start() == 0);
42        assert!(region.len() == 5);
43        assert!(region.reserved() == PAGE_SIZE);
44
45        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
46    }
47
48    database.write_all_to_region(region1_i.into(), &[5, 6, 7, 8, 9])?;
49
50    {
51        let region = database.get_region(region1_i.into())?;
52        assert!(region.start() == 0);
53        assert!(region.len() == 10);
54        assert!(region.reserved() == PAGE_SIZE);
55
56        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
57    }
58
59    database.write_all_to_region_at(region1_i.into(), &[1, 2], 0)?;
60
61    {
62        let region = database.get_region(region1_i.into())?;
63        assert!(region.start() == 0);
64        assert!(region.len() == 10);
65        assert!(region.reserved() == PAGE_SIZE);
66
67        assert!(database.mmap()[0..10] == [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]);
68    }
69
70    database.write_all_to_region_at(region1_i.into(), &[10, 11, 12, 13, 14, 15, 16, 17, 18], 4)?;
71
72    {
73        let region = database.get_region(region1_i.into())?;
74        assert!(region.start() == 0);
75        assert!(region.len() == 13);
76        assert!(region.reserved() == PAGE_SIZE);
77
78        assert!(
79            database.mmap()[0..20]
80                == [
81                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0
82                ]
83        );
84    }
85
86    database.write_all_to_region_at(region1_i.into(), &[0, 0, 0, 0, 0, 1], 13)?;
87
88    {
89        let region = database.get_region(region1_i.into())?;
90        assert!(region.start() == 0);
91        assert!(region.len() == 19);
92        assert!(region.reserved() == PAGE_SIZE);
93
94        assert!(
95            database.mmap()[0..20]
96                == [
97                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 1, 0
98                ]
99        );
100    }
101
102    dbg!(1);
103
104    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
105
106    {
107        let region = database.get_region(region1_i.into())?;
108        assert!(region.start() == 0);
109        assert!(region.len() == 8000);
110        assert!(region.reserved() == PAGE_SIZE * 2);
111
112        assert!(database.mmap()[0..8000] == [1; 8000]);
113        assert!(database.mmap()[8000..8001] == [0]);
114    }
115
116    println!("Disk usage - pre sync: {}", database.disk_usage());
117    database.flush()?;
118    println!("Disk usage - post sync: {}", database.disk_usage());
119
120    database.truncate_region(region1_i.into(), 10)?;
121    database.punch_holes()?;
122
123    {
124        let region = database.get_region(region1_i.into())?;
125        assert!(region.start() == 0);
126        assert!(region.len() == 10);
127        assert!(region.reserved() == PAGE_SIZE * 2);
128        // We only punch a hole in whole pages (4096 bytes)
129        // Thus the last byte of the page where the is still data wasn't overwritten when truncating
130        // And the first byte of the punched page was set to 0
131        assert!(database.mmap()[4095..=4096] == [1, 0]);
132    }
133
134    database.flush()?;
135    println!("Disk usage - post trunc: {}", database.disk_usage());
136
137    database.remove_region(region1_i.into())?;
138
139    database.flush()?;
140
141    println!("Disk usage - post remove: {}", database.disk_usage());
142
143    {
144        let regions = database.regions();
145        let index_to_region = regions.index_to_region();
146        assert!(index_to_region.len() == 1);
147        assert!(index_to_region[0].is_none());
148        assert!(regions.id_to_index().is_empty());
149
150        let layout = database.layout();
151        assert!(layout.start_to_index().is_empty());
152        assert!(layout.start_to_hole().len() == 1);
153    }
154
155    let (region1_i, _) = database.create_region_if_needed("region1")?;
156    let (region2_i, _) = database.create_region_if_needed("region2")?;
157    let (region3_i, _) = database.create_region_if_needed("region3")?;
158
159    // dbg!(seqdb.layout());
160
161    {
162        let regions = database.regions();
163        let index_to_region = regions.index_to_region();
164        assert!(index_to_region.len() == 3);
165        let region1 = database.get_region(region1_i.into())?;
166        assert!(region1.start() == 0);
167        assert!(region1.len() == 0);
168        assert!(region1.reserved() == PAGE_SIZE);
169        let region2 = database.get_region(region2_i.into())?;
170        assert!(region2.start() == PAGE_SIZE);
171        assert!(region2.len() == 0);
172        assert!(region2.reserved() == PAGE_SIZE);
173        let region3 = database.get_region(region3_i.into())?;
174        assert!(region3.start() == PAGE_SIZE * 2);
175        assert!(region3.len() == 0);
176        assert!(region3.reserved() == PAGE_SIZE);
177        let id_to_index = regions.id_to_index();
178        assert!(id_to_index.len() == 3);
179        assert!(id_to_index.get("region1") == Some(&0));
180        assert!(id_to_index.get("region2") == Some(&1));
181        assert!(id_to_index.get("region3") == Some(&2));
182
183        let layout = database.layout();
184        let start_to_index = layout.start_to_index();
185        assert!(start_to_index.len() == 3);
186        assert!(start_to_index.get(&0) == Some(&0));
187        assert!(start_to_index.get(&PAGE_SIZE) == Some(&1));
188        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&2));
189        assert!(layout.start_to_hole().is_empty());
190    }
191
192    database.remove_region(region2_i.into())?;
193
194    {
195        let regions = database.regions();
196        let index_to_region = regions.index_to_region();
197        assert!(index_to_region.len() == 3);
198        let region1 = database.get_region(region1_i.into())?;
199        assert!(region1.start() == 0);
200        assert!(region1.len() == 0);
201        assert!(region1.reserved() == PAGE_SIZE);
202        assert!(database.get_region(region2_i.into()).is_err());
203        assert!(
204            index_to_region
205                .get(region2_i)
206                .is_some_and(|opt| opt.is_none())
207        );
208        let region3 = database.get_region(region3_i.into())?;
209        assert!(region3.start() == PAGE_SIZE * 2);
210        assert!(region3.len() == 0);
211        assert!(region3.reserved() == PAGE_SIZE);
212        let id_to_index = regions.id_to_index();
213        assert!(id_to_index.len() == 2);
214        assert!(id_to_index.get("region1") == Some(&0));
215        assert!(id_to_index.get("region2").is_none());
216        assert!(id_to_index.get("region3") == Some(&2));
217
218        let layout = database.layout();
219        let start_to_index = layout.start_to_index();
220        assert!(start_to_index.len() == 2);
221        assert!(start_to_index.get(&0) == Some(&region1_i));
222        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
223        let start_to_hole = layout.start_to_hole();
224        assert!(start_to_hole.len() == 1);
225        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
226
227        drop(regions);
228        drop(layout);
229        assert!(
230            database
231                .remove_region(region2_i.into())
232                .is_ok_and(|o| o.is_none())
233        );
234    }
235
236    let (region2_i, _) = database.create_region_if_needed("region2")?;
237
238    {
239        assert!(region2_i == 1)
240    }
241
242    database.remove_region(region2_i.into())?;
243
244    {
245        let regions = database.regions();
246        let index_to_region = regions.index_to_region();
247        assert!(index_to_region.len() == 3);
248        let region1 = database.get_region(region1_i.into())?;
249        assert!(region1.start() == 0);
250        assert!(region1.len() == 0);
251        assert!(region1.reserved() == PAGE_SIZE);
252        assert!(database.get_region(region2_i.into()).is_err());
253        assert!(
254            index_to_region
255                .get(region2_i)
256                .is_some_and(|opt| opt.is_none())
257        );
258        let region3 = database.get_region(region3_i.into())?;
259        assert!(region3.start() == PAGE_SIZE * 2);
260        assert!(region3.len() == 0);
261        assert!(region3.reserved() == PAGE_SIZE);
262        let id_to_index = regions.id_to_index();
263        assert!(id_to_index.len() == 2);
264        assert!(id_to_index.get("region1") == Some(&0));
265        assert!(id_to_index.get("region2").is_none());
266        assert!(id_to_index.get("region3") == Some(&2));
267
268        let layout = database.layout();
269        let start_to_index = layout.start_to_index();
270        assert!(start_to_index.len() == 2);
271        assert!(start_to_index.get(&0) == Some(&region1_i));
272        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
273        let start_to_hole = layout.start_to_hole();
274        assert!(start_to_hole.len() == 1);
275        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
276
277        drop(regions);
278        drop(layout);
279        assert!(
280            database
281                .remove_region(region2_i.into())
282                .is_ok_and(|o| o.is_none())
283        );
284    }
285
286    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
287
288    {
289        let regions = database.regions();
290        let index_to_region = regions.index_to_region();
291        assert!(index_to_region.len() == 3);
292        let region1 = database.get_region(region1_i.into())?;
293        assert!(region1.start() == 0);
294        assert!(region1.len() == 8000);
295        assert!(region1.reserved() == 2 * PAGE_SIZE);
296        assert!(database.get_region(region2_i.into()).is_err());
297        assert!(
298            index_to_region
299                .get(region2_i)
300                .is_some_and(|opt| opt.is_none())
301        );
302        let region3 = database.get_region(region3_i.into())?;
303        assert!(region3.start() == PAGE_SIZE * 2);
304        assert!(region3.len() == 0);
305        assert!(region3.reserved() == PAGE_SIZE);
306        let id_to_index = regions.id_to_index();
307        assert!(id_to_index.len() == 2);
308        assert!(id_to_index.get("region1") == Some(&0));
309        assert!(id_to_index.get("region2").is_none());
310        assert!(id_to_index.get("region3") == Some(&2));
311
312        let layout = database.layout();
313        let start_to_index = layout.start_to_index();
314        assert!(start_to_index.len() == 2);
315        assert!(start_to_index.get(&0) == Some(&region1_i));
316        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
317        let start_to_hole = layout.start_to_hole();
318        assert!(start_to_hole.is_empty());
319    }
320
321    let (region2_i, _) = database.create_region_if_needed("region2")?;
322
323    {
324        let regions = database.regions();
325        let index_to_region = regions.index_to_region();
326        assert!(index_to_region.len() == 3);
327        let region1 = database.get_region(region1_i.into())?;
328        assert!(region1.start() == 0);
329        assert!(region1.len() == 8000);
330        assert!(region1.reserved() == 2 * PAGE_SIZE);
331        let region2 = database.get_region(region2_i.into())?;
332        assert!(region2.start() == PAGE_SIZE * 3);
333        assert!(region2.len() == 0);
334        assert!(region2.reserved() == PAGE_SIZE);
335        let region3 = database.get_region(region3_i.into())?;
336        assert!(region3.start() == PAGE_SIZE * 2);
337        assert!(region3.len() == 0);
338        assert!(region3.reserved() == PAGE_SIZE);
339        let id_to_index = regions.id_to_index();
340        assert!(id_to_index.len() == 3);
341        assert!(id_to_index.get("region1") == Some(&0));
342        assert!(id_to_index.get("region2") == Some(&1));
343        assert!(id_to_index.get("region3") == Some(&2));
344
345        let layout = database.layout();
346        let start_to_index = layout.start_to_index();
347        assert!(start_to_index.len() == 3);
348        assert!(start_to_index.get(&0) == Some(&region1_i));
349        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
350        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
351        let start_to_hole = layout.start_to_hole();
352        assert!(start_to_hole.is_empty());
353    }
354
355    database.remove_region(region3_i.into())?;
356
357    {
358        let regions = database.regions();
359        let index_to_region = regions.index_to_region();
360        assert!(index_to_region.len() == 3);
361        let region1 = database.get_region(region1_i.into())?;
362        assert!(region1.start() == 0);
363        assert!(region1.len() == 8000);
364        assert!(region1.reserved() == 2 * PAGE_SIZE);
365        let region2 = database.get_region(region2_i.into())?;
366        assert!(region2.start() == PAGE_SIZE * 3);
367        assert!(region2.len() == 0);
368        assert!(region2.reserved() == PAGE_SIZE);
369        assert!(database.get_region(region3_i.into()).is_err());
370        let id_to_index = regions.id_to_index();
371        assert!(id_to_index.len() == 2);
372        assert!(id_to_index.get("region1") == Some(&0));
373        assert!(id_to_index.get("region2") == Some(&1));
374        assert!(id_to_index.get("region3").is_none());
375
376        let layout = database.layout();
377        let start_to_index = layout.start_to_index();
378        assert!(start_to_index.len() == 2);
379        assert!(start_to_index.get(&0) == Some(&region1_i));
380        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
381        let start_to_hole = layout.start_to_hole();
382        assert!(start_to_hole.get(&(PAGE_SIZE * 2)) == Some(&PAGE_SIZE));
383    }
384
385    database.write_all_to_region(region1_i.into(), &[1; 8000])?;
386
387    {
388        let regions = database.regions();
389        let index_to_region = regions.index_to_region();
390        assert!(index_to_region.len() == 3);
391        let region1 = database.get_region(region1_i.into())?;
392        assert!(region1.start() == PAGE_SIZE * 4);
393        assert!(region1.len() == 16_000);
394        assert!(region1.reserved() == 4 * PAGE_SIZE);
395        let region2 = database.get_region(region2_i.into())?;
396        assert!(region2.start() == PAGE_SIZE * 3);
397        assert!(region2.len() == 0);
398        assert!(region2.reserved() == PAGE_SIZE);
399        assert!(database.get_region(region3_i.into()).is_err());
400        let id_to_index = regions.id_to_index();
401        assert!(id_to_index.len() == 2);
402        assert!(id_to_index.get("region1") == Some(&0));
403        assert!(id_to_index.get("region2") == Some(&1));
404        assert!(id_to_index.get("region3").is_none());
405
406        let layout = database.layout();
407        let start_to_index = layout.start_to_index();
408        assert!(start_to_index.len() == 2);
409        assert!(start_to_index.get(&(PAGE_SIZE * 4)) == Some(&region1_i));
410        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
411        let start_to_hole = layout.start_to_hole();
412        assert!(start_to_hole.get(&0) == Some(&(PAGE_SIZE * 3)));
413    }
414
415    database.write_all_to_region(region2_i.into(), &[1; 6000])?;
416
417    let (region4_i, _) = database.create_region_if_needed("region4")?;
418    database.remove_region(region2_i.into())?;
419    database.remove_region(region4_i.into())?;
420
421    let regions = database.regions();
422    dbg!(&regions);
423    let layout = database.layout();
424    dbg!(&layout);
425
426    Ok(())
427}
Source

pub fn create_region_reader<'a>( &'a self, identifier: Identifier, ) -> Result<Reader<'a>>

Source

pub fn write_all_to_region( &self, identifier: Identifier, data: &[u8], ) -> Result<()>

Examples found in repository?
examples/db.rs (line 37)
5fn main() -> Result<()> {
6    let _ = fs::remove_dir_all("vecs");
7
8    let database = Database::open(Path::new("vecs"))?;
9
10    // let seqdb_min_len = PAGE_SIZE * 1_000_000;
11    // let min_regions = 20_000;
12
13    // seqdb.set_min_len(seqdb_min_len)?;
14    // seqdb.set_min_regions(min_regions)?;
15
16    let (region1_i, _) = database.create_region_if_needed("region1")?;
17
18    {
19        let layout = database.layout();
20        assert!(layout.start_to_index().len() == 1);
21        assert!(layout.start_to_index().first_key_value() == Some((&0, &0)));
22        assert!(layout.start_to_hole().is_empty());
23
24        let regions = database.regions();
25        assert!(
26            regions
27                .get_region_index_from_id("region1")
28                .is_some_and(|i| i == region1_i)
29        );
30
31        let region = database.get_region(region1_i.into())?;
32        assert!(region.start() == 0);
33        assert!(region.len() == 0);
34        assert!(region.reserved() == PAGE_SIZE);
35    }
36
37    database.write_all_to_region(region1_i.into(), &[0, 1, 2, 3, 4])?;
38
39    {
40        let region = database.get_region(region1_i.into())?;
41        assert!(region.start() == 0);
42        assert!(region.len() == 5);
43        assert!(region.reserved() == PAGE_SIZE);
44
45        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
46    }
47
48    database.write_all_to_region(region1_i.into(), &[5, 6, 7, 8, 9])?;
49
50    {
51        let region = database.get_region(region1_i.into())?;
52        assert!(region.start() == 0);
53        assert!(region.len() == 10);
54        assert!(region.reserved() == PAGE_SIZE);
55
56        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
57    }
58
59    database.write_all_to_region_at(region1_i.into(), &[1, 2], 0)?;
60
61    {
62        let region = database.get_region(region1_i.into())?;
63        assert!(region.start() == 0);
64        assert!(region.len() == 10);
65        assert!(region.reserved() == PAGE_SIZE);
66
67        assert!(database.mmap()[0..10] == [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]);
68    }
69
70    database.write_all_to_region_at(region1_i.into(), &[10, 11, 12, 13, 14, 15, 16, 17, 18], 4)?;
71
72    {
73        let region = database.get_region(region1_i.into())?;
74        assert!(region.start() == 0);
75        assert!(region.len() == 13);
76        assert!(region.reserved() == PAGE_SIZE);
77
78        assert!(
79            database.mmap()[0..20]
80                == [
81                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0
82                ]
83        );
84    }
85
86    database.write_all_to_region_at(region1_i.into(), &[0, 0, 0, 0, 0, 1], 13)?;
87
88    {
89        let region = database.get_region(region1_i.into())?;
90        assert!(region.start() == 0);
91        assert!(region.len() == 19);
92        assert!(region.reserved() == PAGE_SIZE);
93
94        assert!(
95            database.mmap()[0..20]
96                == [
97                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 1, 0
98                ]
99        );
100    }
101
102    dbg!(1);
103
104    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
105
106    {
107        let region = database.get_region(region1_i.into())?;
108        assert!(region.start() == 0);
109        assert!(region.len() == 8000);
110        assert!(region.reserved() == PAGE_SIZE * 2);
111
112        assert!(database.mmap()[0..8000] == [1; 8000]);
113        assert!(database.mmap()[8000..8001] == [0]);
114    }
115
116    println!("Disk usage - pre sync: {}", database.disk_usage());
117    database.flush()?;
118    println!("Disk usage - post sync: {}", database.disk_usage());
119
120    database.truncate_region(region1_i.into(), 10)?;
121    database.punch_holes()?;
122
123    {
124        let region = database.get_region(region1_i.into())?;
125        assert!(region.start() == 0);
126        assert!(region.len() == 10);
127        assert!(region.reserved() == PAGE_SIZE * 2);
128        // We only punch a hole in whole pages (4096 bytes)
129        // Thus the last byte of the page where the is still data wasn't overwritten when truncating
130        // And the first byte of the punched page was set to 0
131        assert!(database.mmap()[4095..=4096] == [1, 0]);
132    }
133
134    database.flush()?;
135    println!("Disk usage - post trunc: {}", database.disk_usage());
136
137    database.remove_region(region1_i.into())?;
138
139    database.flush()?;
140
141    println!("Disk usage - post remove: {}", database.disk_usage());
142
143    {
144        let regions = database.regions();
145        let index_to_region = regions.index_to_region();
146        assert!(index_to_region.len() == 1);
147        assert!(index_to_region[0].is_none());
148        assert!(regions.id_to_index().is_empty());
149
150        let layout = database.layout();
151        assert!(layout.start_to_index().is_empty());
152        assert!(layout.start_to_hole().len() == 1);
153    }
154
155    let (region1_i, _) = database.create_region_if_needed("region1")?;
156    let (region2_i, _) = database.create_region_if_needed("region2")?;
157    let (region3_i, _) = database.create_region_if_needed("region3")?;
158
159    // dbg!(seqdb.layout());
160
161    {
162        let regions = database.regions();
163        let index_to_region = regions.index_to_region();
164        assert!(index_to_region.len() == 3);
165        let region1 = database.get_region(region1_i.into())?;
166        assert!(region1.start() == 0);
167        assert!(region1.len() == 0);
168        assert!(region1.reserved() == PAGE_SIZE);
169        let region2 = database.get_region(region2_i.into())?;
170        assert!(region2.start() == PAGE_SIZE);
171        assert!(region2.len() == 0);
172        assert!(region2.reserved() == PAGE_SIZE);
173        let region3 = database.get_region(region3_i.into())?;
174        assert!(region3.start() == PAGE_SIZE * 2);
175        assert!(region3.len() == 0);
176        assert!(region3.reserved() == PAGE_SIZE);
177        let id_to_index = regions.id_to_index();
178        assert!(id_to_index.len() == 3);
179        assert!(id_to_index.get("region1") == Some(&0));
180        assert!(id_to_index.get("region2") == Some(&1));
181        assert!(id_to_index.get("region3") == Some(&2));
182
183        let layout = database.layout();
184        let start_to_index = layout.start_to_index();
185        assert!(start_to_index.len() == 3);
186        assert!(start_to_index.get(&0) == Some(&0));
187        assert!(start_to_index.get(&PAGE_SIZE) == Some(&1));
188        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&2));
189        assert!(layout.start_to_hole().is_empty());
190    }
191
192    database.remove_region(region2_i.into())?;
193
194    {
195        let regions = database.regions();
196        let index_to_region = regions.index_to_region();
197        assert!(index_to_region.len() == 3);
198        let region1 = database.get_region(region1_i.into())?;
199        assert!(region1.start() == 0);
200        assert!(region1.len() == 0);
201        assert!(region1.reserved() == PAGE_SIZE);
202        assert!(database.get_region(region2_i.into()).is_err());
203        assert!(
204            index_to_region
205                .get(region2_i)
206                .is_some_and(|opt| opt.is_none())
207        );
208        let region3 = database.get_region(region3_i.into())?;
209        assert!(region3.start() == PAGE_SIZE * 2);
210        assert!(region3.len() == 0);
211        assert!(region3.reserved() == PAGE_SIZE);
212        let id_to_index = regions.id_to_index();
213        assert!(id_to_index.len() == 2);
214        assert!(id_to_index.get("region1") == Some(&0));
215        assert!(id_to_index.get("region2").is_none());
216        assert!(id_to_index.get("region3") == Some(&2));
217
218        let layout = database.layout();
219        let start_to_index = layout.start_to_index();
220        assert!(start_to_index.len() == 2);
221        assert!(start_to_index.get(&0) == Some(&region1_i));
222        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
223        let start_to_hole = layout.start_to_hole();
224        assert!(start_to_hole.len() == 1);
225        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
226
227        drop(regions);
228        drop(layout);
229        assert!(
230            database
231                .remove_region(region2_i.into())
232                .is_ok_and(|o| o.is_none())
233        );
234    }
235
236    let (region2_i, _) = database.create_region_if_needed("region2")?;
237
238    {
239        assert!(region2_i == 1)
240    }
241
242    database.remove_region(region2_i.into())?;
243
244    {
245        let regions = database.regions();
246        let index_to_region = regions.index_to_region();
247        assert!(index_to_region.len() == 3);
248        let region1 = database.get_region(region1_i.into())?;
249        assert!(region1.start() == 0);
250        assert!(region1.len() == 0);
251        assert!(region1.reserved() == PAGE_SIZE);
252        assert!(database.get_region(region2_i.into()).is_err());
253        assert!(
254            index_to_region
255                .get(region2_i)
256                .is_some_and(|opt| opt.is_none())
257        );
258        let region3 = database.get_region(region3_i.into())?;
259        assert!(region3.start() == PAGE_SIZE * 2);
260        assert!(region3.len() == 0);
261        assert!(region3.reserved() == PAGE_SIZE);
262        let id_to_index = regions.id_to_index();
263        assert!(id_to_index.len() == 2);
264        assert!(id_to_index.get("region1") == Some(&0));
265        assert!(id_to_index.get("region2").is_none());
266        assert!(id_to_index.get("region3") == Some(&2));
267
268        let layout = database.layout();
269        let start_to_index = layout.start_to_index();
270        assert!(start_to_index.len() == 2);
271        assert!(start_to_index.get(&0) == Some(&region1_i));
272        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
273        let start_to_hole = layout.start_to_hole();
274        assert!(start_to_hole.len() == 1);
275        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
276
277        drop(regions);
278        drop(layout);
279        assert!(
280            database
281                .remove_region(region2_i.into())
282                .is_ok_and(|o| o.is_none())
283        );
284    }
285
286    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
287
288    {
289        let regions = database.regions();
290        let index_to_region = regions.index_to_region();
291        assert!(index_to_region.len() == 3);
292        let region1 = database.get_region(region1_i.into())?;
293        assert!(region1.start() == 0);
294        assert!(region1.len() == 8000);
295        assert!(region1.reserved() == 2 * PAGE_SIZE);
296        assert!(database.get_region(region2_i.into()).is_err());
297        assert!(
298            index_to_region
299                .get(region2_i)
300                .is_some_and(|opt| opt.is_none())
301        );
302        let region3 = database.get_region(region3_i.into())?;
303        assert!(region3.start() == PAGE_SIZE * 2);
304        assert!(region3.len() == 0);
305        assert!(region3.reserved() == PAGE_SIZE);
306        let id_to_index = regions.id_to_index();
307        assert!(id_to_index.len() == 2);
308        assert!(id_to_index.get("region1") == Some(&0));
309        assert!(id_to_index.get("region2").is_none());
310        assert!(id_to_index.get("region3") == Some(&2));
311
312        let layout = database.layout();
313        let start_to_index = layout.start_to_index();
314        assert!(start_to_index.len() == 2);
315        assert!(start_to_index.get(&0) == Some(&region1_i));
316        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
317        let start_to_hole = layout.start_to_hole();
318        assert!(start_to_hole.is_empty());
319    }
320
321    let (region2_i, _) = database.create_region_if_needed("region2")?;
322
323    {
324        let regions = database.regions();
325        let index_to_region = regions.index_to_region();
326        assert!(index_to_region.len() == 3);
327        let region1 = database.get_region(region1_i.into())?;
328        assert!(region1.start() == 0);
329        assert!(region1.len() == 8000);
330        assert!(region1.reserved() == 2 * PAGE_SIZE);
331        let region2 = database.get_region(region2_i.into())?;
332        assert!(region2.start() == PAGE_SIZE * 3);
333        assert!(region2.len() == 0);
334        assert!(region2.reserved() == PAGE_SIZE);
335        let region3 = database.get_region(region3_i.into())?;
336        assert!(region3.start() == PAGE_SIZE * 2);
337        assert!(region3.len() == 0);
338        assert!(region3.reserved() == PAGE_SIZE);
339        let id_to_index = regions.id_to_index();
340        assert!(id_to_index.len() == 3);
341        assert!(id_to_index.get("region1") == Some(&0));
342        assert!(id_to_index.get("region2") == Some(&1));
343        assert!(id_to_index.get("region3") == Some(&2));
344
345        let layout = database.layout();
346        let start_to_index = layout.start_to_index();
347        assert!(start_to_index.len() == 3);
348        assert!(start_to_index.get(&0) == Some(&region1_i));
349        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
350        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
351        let start_to_hole = layout.start_to_hole();
352        assert!(start_to_hole.is_empty());
353    }
354
355    database.remove_region(region3_i.into())?;
356
357    {
358        let regions = database.regions();
359        let index_to_region = regions.index_to_region();
360        assert!(index_to_region.len() == 3);
361        let region1 = database.get_region(region1_i.into())?;
362        assert!(region1.start() == 0);
363        assert!(region1.len() == 8000);
364        assert!(region1.reserved() == 2 * PAGE_SIZE);
365        let region2 = database.get_region(region2_i.into())?;
366        assert!(region2.start() == PAGE_SIZE * 3);
367        assert!(region2.len() == 0);
368        assert!(region2.reserved() == PAGE_SIZE);
369        assert!(database.get_region(region3_i.into()).is_err());
370        let id_to_index = regions.id_to_index();
371        assert!(id_to_index.len() == 2);
372        assert!(id_to_index.get("region1") == Some(&0));
373        assert!(id_to_index.get("region2") == Some(&1));
374        assert!(id_to_index.get("region3").is_none());
375
376        let layout = database.layout();
377        let start_to_index = layout.start_to_index();
378        assert!(start_to_index.len() == 2);
379        assert!(start_to_index.get(&0) == Some(&region1_i));
380        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
381        let start_to_hole = layout.start_to_hole();
382        assert!(start_to_hole.get(&(PAGE_SIZE * 2)) == Some(&PAGE_SIZE));
383    }
384
385    database.write_all_to_region(region1_i.into(), &[1; 8000])?;
386
387    {
388        let regions = database.regions();
389        let index_to_region = regions.index_to_region();
390        assert!(index_to_region.len() == 3);
391        let region1 = database.get_region(region1_i.into())?;
392        assert!(region1.start() == PAGE_SIZE * 4);
393        assert!(region1.len() == 16_000);
394        assert!(region1.reserved() == 4 * PAGE_SIZE);
395        let region2 = database.get_region(region2_i.into())?;
396        assert!(region2.start() == PAGE_SIZE * 3);
397        assert!(region2.len() == 0);
398        assert!(region2.reserved() == PAGE_SIZE);
399        assert!(database.get_region(region3_i.into()).is_err());
400        let id_to_index = regions.id_to_index();
401        assert!(id_to_index.len() == 2);
402        assert!(id_to_index.get("region1") == Some(&0));
403        assert!(id_to_index.get("region2") == Some(&1));
404        assert!(id_to_index.get("region3").is_none());
405
406        let layout = database.layout();
407        let start_to_index = layout.start_to_index();
408        assert!(start_to_index.len() == 2);
409        assert!(start_to_index.get(&(PAGE_SIZE * 4)) == Some(&region1_i));
410        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
411        let start_to_hole = layout.start_to_hole();
412        assert!(start_to_hole.get(&0) == Some(&(PAGE_SIZE * 3)));
413    }
414
415    database.write_all_to_region(region2_i.into(), &[1; 6000])?;
416
417    let (region4_i, _) = database.create_region_if_needed("region4")?;
418    database.remove_region(region2_i.into())?;
419    database.remove_region(region4_i.into())?;
420
421    let regions = database.regions();
422    dbg!(&regions);
423    let layout = database.layout();
424    dbg!(&layout);
425
426    Ok(())
427}
Source

pub fn write_all_to_region_at( &self, identifier: Identifier, data: &[u8], at: u64, ) -> Result<()>

Examples found in repository?
examples/db.rs (line 59)
5fn main() -> Result<()> {
6    let _ = fs::remove_dir_all("vecs");
7
8    let database = Database::open(Path::new("vecs"))?;
9
10    // let seqdb_min_len = PAGE_SIZE * 1_000_000;
11    // let min_regions = 20_000;
12
13    // seqdb.set_min_len(seqdb_min_len)?;
14    // seqdb.set_min_regions(min_regions)?;
15
16    let (region1_i, _) = database.create_region_if_needed("region1")?;
17
18    {
19        let layout = database.layout();
20        assert!(layout.start_to_index().len() == 1);
21        assert!(layout.start_to_index().first_key_value() == Some((&0, &0)));
22        assert!(layout.start_to_hole().is_empty());
23
24        let regions = database.regions();
25        assert!(
26            regions
27                .get_region_index_from_id("region1")
28                .is_some_and(|i| i == region1_i)
29        );
30
31        let region = database.get_region(region1_i.into())?;
32        assert!(region.start() == 0);
33        assert!(region.len() == 0);
34        assert!(region.reserved() == PAGE_SIZE);
35    }
36
37    database.write_all_to_region(region1_i.into(), &[0, 1, 2, 3, 4])?;
38
39    {
40        let region = database.get_region(region1_i.into())?;
41        assert!(region.start() == 0);
42        assert!(region.len() == 5);
43        assert!(region.reserved() == PAGE_SIZE);
44
45        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
46    }
47
48    database.write_all_to_region(region1_i.into(), &[5, 6, 7, 8, 9])?;
49
50    {
51        let region = database.get_region(region1_i.into())?;
52        assert!(region.start() == 0);
53        assert!(region.len() == 10);
54        assert!(region.reserved() == PAGE_SIZE);
55
56        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
57    }
58
59    database.write_all_to_region_at(region1_i.into(), &[1, 2], 0)?;
60
61    {
62        let region = database.get_region(region1_i.into())?;
63        assert!(region.start() == 0);
64        assert!(region.len() == 10);
65        assert!(region.reserved() == PAGE_SIZE);
66
67        assert!(database.mmap()[0..10] == [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]);
68    }
69
70    database.write_all_to_region_at(region1_i.into(), &[10, 11, 12, 13, 14, 15, 16, 17, 18], 4)?;
71
72    {
73        let region = database.get_region(region1_i.into())?;
74        assert!(region.start() == 0);
75        assert!(region.len() == 13);
76        assert!(region.reserved() == PAGE_SIZE);
77
78        assert!(
79            database.mmap()[0..20]
80                == [
81                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0
82                ]
83        );
84    }
85
86    database.write_all_to_region_at(region1_i.into(), &[0, 0, 0, 0, 0, 1], 13)?;
87
88    {
89        let region = database.get_region(region1_i.into())?;
90        assert!(region.start() == 0);
91        assert!(region.len() == 19);
92        assert!(region.reserved() == PAGE_SIZE);
93
94        assert!(
95            database.mmap()[0..20]
96                == [
97                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 1, 0
98                ]
99        );
100    }
101
102    dbg!(1);
103
104    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
105
106    {
107        let region = database.get_region(region1_i.into())?;
108        assert!(region.start() == 0);
109        assert!(region.len() == 8000);
110        assert!(region.reserved() == PAGE_SIZE * 2);
111
112        assert!(database.mmap()[0..8000] == [1; 8000]);
113        assert!(database.mmap()[8000..8001] == [0]);
114    }
115
116    println!("Disk usage - pre sync: {}", database.disk_usage());
117    database.flush()?;
118    println!("Disk usage - post sync: {}", database.disk_usage());
119
120    database.truncate_region(region1_i.into(), 10)?;
121    database.punch_holes()?;
122
123    {
124        let region = database.get_region(region1_i.into())?;
125        assert!(region.start() == 0);
126        assert!(region.len() == 10);
127        assert!(region.reserved() == PAGE_SIZE * 2);
128        // We only punch a hole in whole pages (4096 bytes)
129        // Thus the last byte of the page where the is still data wasn't overwritten when truncating
130        // And the first byte of the punched page was set to 0
131        assert!(database.mmap()[4095..=4096] == [1, 0]);
132    }
133
134    database.flush()?;
135    println!("Disk usage - post trunc: {}", database.disk_usage());
136
137    database.remove_region(region1_i.into())?;
138
139    database.flush()?;
140
141    println!("Disk usage - post remove: {}", database.disk_usage());
142
143    {
144        let regions = database.regions();
145        let index_to_region = regions.index_to_region();
146        assert!(index_to_region.len() == 1);
147        assert!(index_to_region[0].is_none());
148        assert!(regions.id_to_index().is_empty());
149
150        let layout = database.layout();
151        assert!(layout.start_to_index().is_empty());
152        assert!(layout.start_to_hole().len() == 1);
153    }
154
155    let (region1_i, _) = database.create_region_if_needed("region1")?;
156    let (region2_i, _) = database.create_region_if_needed("region2")?;
157    let (region3_i, _) = database.create_region_if_needed("region3")?;
158
159    // dbg!(seqdb.layout());
160
161    {
162        let regions = database.regions();
163        let index_to_region = regions.index_to_region();
164        assert!(index_to_region.len() == 3);
165        let region1 = database.get_region(region1_i.into())?;
166        assert!(region1.start() == 0);
167        assert!(region1.len() == 0);
168        assert!(region1.reserved() == PAGE_SIZE);
169        let region2 = database.get_region(region2_i.into())?;
170        assert!(region2.start() == PAGE_SIZE);
171        assert!(region2.len() == 0);
172        assert!(region2.reserved() == PAGE_SIZE);
173        let region3 = database.get_region(region3_i.into())?;
174        assert!(region3.start() == PAGE_SIZE * 2);
175        assert!(region3.len() == 0);
176        assert!(region3.reserved() == PAGE_SIZE);
177        let id_to_index = regions.id_to_index();
178        assert!(id_to_index.len() == 3);
179        assert!(id_to_index.get("region1") == Some(&0));
180        assert!(id_to_index.get("region2") == Some(&1));
181        assert!(id_to_index.get("region3") == Some(&2));
182
183        let layout = database.layout();
184        let start_to_index = layout.start_to_index();
185        assert!(start_to_index.len() == 3);
186        assert!(start_to_index.get(&0) == Some(&0));
187        assert!(start_to_index.get(&PAGE_SIZE) == Some(&1));
188        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&2));
189        assert!(layout.start_to_hole().is_empty());
190    }
191
192    database.remove_region(region2_i.into())?;
193
194    {
195        let regions = database.regions();
196        let index_to_region = regions.index_to_region();
197        assert!(index_to_region.len() == 3);
198        let region1 = database.get_region(region1_i.into())?;
199        assert!(region1.start() == 0);
200        assert!(region1.len() == 0);
201        assert!(region1.reserved() == PAGE_SIZE);
202        assert!(database.get_region(region2_i.into()).is_err());
203        assert!(
204            index_to_region
205                .get(region2_i)
206                .is_some_and(|opt| opt.is_none())
207        );
208        let region3 = database.get_region(region3_i.into())?;
209        assert!(region3.start() == PAGE_SIZE * 2);
210        assert!(region3.len() == 0);
211        assert!(region3.reserved() == PAGE_SIZE);
212        let id_to_index = regions.id_to_index();
213        assert!(id_to_index.len() == 2);
214        assert!(id_to_index.get("region1") == Some(&0));
215        assert!(id_to_index.get("region2").is_none());
216        assert!(id_to_index.get("region3") == Some(&2));
217
218        let layout = database.layout();
219        let start_to_index = layout.start_to_index();
220        assert!(start_to_index.len() == 2);
221        assert!(start_to_index.get(&0) == Some(&region1_i));
222        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
223        let start_to_hole = layout.start_to_hole();
224        assert!(start_to_hole.len() == 1);
225        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
226
227        drop(regions);
228        drop(layout);
229        assert!(
230            database
231                .remove_region(region2_i.into())
232                .is_ok_and(|o| o.is_none())
233        );
234    }
235
236    let (region2_i, _) = database.create_region_if_needed("region2")?;
237
238    {
239        assert!(region2_i == 1)
240    }
241
242    database.remove_region(region2_i.into())?;
243
244    {
245        let regions = database.regions();
246        let index_to_region = regions.index_to_region();
247        assert!(index_to_region.len() == 3);
248        let region1 = database.get_region(region1_i.into())?;
249        assert!(region1.start() == 0);
250        assert!(region1.len() == 0);
251        assert!(region1.reserved() == PAGE_SIZE);
252        assert!(database.get_region(region2_i.into()).is_err());
253        assert!(
254            index_to_region
255                .get(region2_i)
256                .is_some_and(|opt| opt.is_none())
257        );
258        let region3 = database.get_region(region3_i.into())?;
259        assert!(region3.start() == PAGE_SIZE * 2);
260        assert!(region3.len() == 0);
261        assert!(region3.reserved() == PAGE_SIZE);
262        let id_to_index = regions.id_to_index();
263        assert!(id_to_index.len() == 2);
264        assert!(id_to_index.get("region1") == Some(&0));
265        assert!(id_to_index.get("region2").is_none());
266        assert!(id_to_index.get("region3") == Some(&2));
267
268        let layout = database.layout();
269        let start_to_index = layout.start_to_index();
270        assert!(start_to_index.len() == 2);
271        assert!(start_to_index.get(&0) == Some(&region1_i));
272        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
273        let start_to_hole = layout.start_to_hole();
274        assert!(start_to_hole.len() == 1);
275        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
276
277        drop(regions);
278        drop(layout);
279        assert!(
280            database
281                .remove_region(region2_i.into())
282                .is_ok_and(|o| o.is_none())
283        );
284    }
285
286    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
287
288    {
289        let regions = database.regions();
290        let index_to_region = regions.index_to_region();
291        assert!(index_to_region.len() == 3);
292        let region1 = database.get_region(region1_i.into())?;
293        assert!(region1.start() == 0);
294        assert!(region1.len() == 8000);
295        assert!(region1.reserved() == 2 * PAGE_SIZE);
296        assert!(database.get_region(region2_i.into()).is_err());
297        assert!(
298            index_to_region
299                .get(region2_i)
300                .is_some_and(|opt| opt.is_none())
301        );
302        let region3 = database.get_region(region3_i.into())?;
303        assert!(region3.start() == PAGE_SIZE * 2);
304        assert!(region3.len() == 0);
305        assert!(region3.reserved() == PAGE_SIZE);
306        let id_to_index = regions.id_to_index();
307        assert!(id_to_index.len() == 2);
308        assert!(id_to_index.get("region1") == Some(&0));
309        assert!(id_to_index.get("region2").is_none());
310        assert!(id_to_index.get("region3") == Some(&2));
311
312        let layout = database.layout();
313        let start_to_index = layout.start_to_index();
314        assert!(start_to_index.len() == 2);
315        assert!(start_to_index.get(&0) == Some(&region1_i));
316        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
317        let start_to_hole = layout.start_to_hole();
318        assert!(start_to_hole.is_empty());
319    }
320
321    let (region2_i, _) = database.create_region_if_needed("region2")?;
322
323    {
324        let regions = database.regions();
325        let index_to_region = regions.index_to_region();
326        assert!(index_to_region.len() == 3);
327        let region1 = database.get_region(region1_i.into())?;
328        assert!(region1.start() == 0);
329        assert!(region1.len() == 8000);
330        assert!(region1.reserved() == 2 * PAGE_SIZE);
331        let region2 = database.get_region(region2_i.into())?;
332        assert!(region2.start() == PAGE_SIZE * 3);
333        assert!(region2.len() == 0);
334        assert!(region2.reserved() == PAGE_SIZE);
335        let region3 = database.get_region(region3_i.into())?;
336        assert!(region3.start() == PAGE_SIZE * 2);
337        assert!(region3.len() == 0);
338        assert!(region3.reserved() == PAGE_SIZE);
339        let id_to_index = regions.id_to_index();
340        assert!(id_to_index.len() == 3);
341        assert!(id_to_index.get("region1") == Some(&0));
342        assert!(id_to_index.get("region2") == Some(&1));
343        assert!(id_to_index.get("region3") == Some(&2));
344
345        let layout = database.layout();
346        let start_to_index = layout.start_to_index();
347        assert!(start_to_index.len() == 3);
348        assert!(start_to_index.get(&0) == Some(&region1_i));
349        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
350        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
351        let start_to_hole = layout.start_to_hole();
352        assert!(start_to_hole.is_empty());
353    }
354
355    database.remove_region(region3_i.into())?;
356
357    {
358        let regions = database.regions();
359        let index_to_region = regions.index_to_region();
360        assert!(index_to_region.len() == 3);
361        let region1 = database.get_region(region1_i.into())?;
362        assert!(region1.start() == 0);
363        assert!(region1.len() == 8000);
364        assert!(region1.reserved() == 2 * PAGE_SIZE);
365        let region2 = database.get_region(region2_i.into())?;
366        assert!(region2.start() == PAGE_SIZE * 3);
367        assert!(region2.len() == 0);
368        assert!(region2.reserved() == PAGE_SIZE);
369        assert!(database.get_region(region3_i.into()).is_err());
370        let id_to_index = regions.id_to_index();
371        assert!(id_to_index.len() == 2);
372        assert!(id_to_index.get("region1") == Some(&0));
373        assert!(id_to_index.get("region2") == Some(&1));
374        assert!(id_to_index.get("region3").is_none());
375
376        let layout = database.layout();
377        let start_to_index = layout.start_to_index();
378        assert!(start_to_index.len() == 2);
379        assert!(start_to_index.get(&0) == Some(&region1_i));
380        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
381        let start_to_hole = layout.start_to_hole();
382        assert!(start_to_hole.get(&(PAGE_SIZE * 2)) == Some(&PAGE_SIZE));
383    }
384
385    database.write_all_to_region(region1_i.into(), &[1; 8000])?;
386
387    {
388        let regions = database.regions();
389        let index_to_region = regions.index_to_region();
390        assert!(index_to_region.len() == 3);
391        let region1 = database.get_region(region1_i.into())?;
392        assert!(region1.start() == PAGE_SIZE * 4);
393        assert!(region1.len() == 16_000);
394        assert!(region1.reserved() == 4 * PAGE_SIZE);
395        let region2 = database.get_region(region2_i.into())?;
396        assert!(region2.start() == PAGE_SIZE * 3);
397        assert!(region2.len() == 0);
398        assert!(region2.reserved() == PAGE_SIZE);
399        assert!(database.get_region(region3_i.into()).is_err());
400        let id_to_index = regions.id_to_index();
401        assert!(id_to_index.len() == 2);
402        assert!(id_to_index.get("region1") == Some(&0));
403        assert!(id_to_index.get("region2") == Some(&1));
404        assert!(id_to_index.get("region3").is_none());
405
406        let layout = database.layout();
407        let start_to_index = layout.start_to_index();
408        assert!(start_to_index.len() == 2);
409        assert!(start_to_index.get(&(PAGE_SIZE * 4)) == Some(&region1_i));
410        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
411        let start_to_hole = layout.start_to_hole();
412        assert!(start_to_hole.get(&0) == Some(&(PAGE_SIZE * 3)));
413    }
414
415    database.write_all_to_region(region2_i.into(), &[1; 6000])?;
416
417    let (region4_i, _) = database.create_region_if_needed("region4")?;
418    database.remove_region(region2_i.into())?;
419    database.remove_region(region4_i.into())?;
420
421    let regions = database.regions();
422    dbg!(&regions);
423    let layout = database.layout();
424    dbg!(&layout);
425
426    Ok(())
427}
Source

pub fn truncate_write_all_to_region( &self, identifier: Identifier, at: u64, data: &[u8], ) -> Result<()>

Source

pub fn truncate_region(&self, identifier: Identifier, from: u64) -> Result<()>

From relative to start

Non destructive

Examples found in repository?
examples/db.rs (line 120)
5fn main() -> Result<()> {
6    let _ = fs::remove_dir_all("vecs");
7
8    let database = Database::open(Path::new("vecs"))?;
9
10    // let seqdb_min_len = PAGE_SIZE * 1_000_000;
11    // let min_regions = 20_000;
12
13    // seqdb.set_min_len(seqdb_min_len)?;
14    // seqdb.set_min_regions(min_regions)?;
15
16    let (region1_i, _) = database.create_region_if_needed("region1")?;
17
18    {
19        let layout = database.layout();
20        assert!(layout.start_to_index().len() == 1);
21        assert!(layout.start_to_index().first_key_value() == Some((&0, &0)));
22        assert!(layout.start_to_hole().is_empty());
23
24        let regions = database.regions();
25        assert!(
26            regions
27                .get_region_index_from_id("region1")
28                .is_some_and(|i| i == region1_i)
29        );
30
31        let region = database.get_region(region1_i.into())?;
32        assert!(region.start() == 0);
33        assert!(region.len() == 0);
34        assert!(region.reserved() == PAGE_SIZE);
35    }
36
37    database.write_all_to_region(region1_i.into(), &[0, 1, 2, 3, 4])?;
38
39    {
40        let region = database.get_region(region1_i.into())?;
41        assert!(region.start() == 0);
42        assert!(region.len() == 5);
43        assert!(region.reserved() == PAGE_SIZE);
44
45        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
46    }
47
48    database.write_all_to_region(region1_i.into(), &[5, 6, 7, 8, 9])?;
49
50    {
51        let region = database.get_region(region1_i.into())?;
52        assert!(region.start() == 0);
53        assert!(region.len() == 10);
54        assert!(region.reserved() == PAGE_SIZE);
55
56        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
57    }
58
59    database.write_all_to_region_at(region1_i.into(), &[1, 2], 0)?;
60
61    {
62        let region = database.get_region(region1_i.into())?;
63        assert!(region.start() == 0);
64        assert!(region.len() == 10);
65        assert!(region.reserved() == PAGE_SIZE);
66
67        assert!(database.mmap()[0..10] == [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]);
68    }
69
70    database.write_all_to_region_at(region1_i.into(), &[10, 11, 12, 13, 14, 15, 16, 17, 18], 4)?;
71
72    {
73        let region = database.get_region(region1_i.into())?;
74        assert!(region.start() == 0);
75        assert!(region.len() == 13);
76        assert!(region.reserved() == PAGE_SIZE);
77
78        assert!(
79            database.mmap()[0..20]
80                == [
81                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0
82                ]
83        );
84    }
85
86    database.write_all_to_region_at(region1_i.into(), &[0, 0, 0, 0, 0, 1], 13)?;
87
88    {
89        let region = database.get_region(region1_i.into())?;
90        assert!(region.start() == 0);
91        assert!(region.len() == 19);
92        assert!(region.reserved() == PAGE_SIZE);
93
94        assert!(
95            database.mmap()[0..20]
96                == [
97                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 1, 0
98                ]
99        );
100    }
101
102    dbg!(1);
103
104    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
105
106    {
107        let region = database.get_region(region1_i.into())?;
108        assert!(region.start() == 0);
109        assert!(region.len() == 8000);
110        assert!(region.reserved() == PAGE_SIZE * 2);
111
112        assert!(database.mmap()[0..8000] == [1; 8000]);
113        assert!(database.mmap()[8000..8001] == [0]);
114    }
115
116    println!("Disk usage - pre sync: {}", database.disk_usage());
117    database.flush()?;
118    println!("Disk usage - post sync: {}", database.disk_usage());
119
120    database.truncate_region(region1_i.into(), 10)?;
121    database.punch_holes()?;
122
123    {
124        let region = database.get_region(region1_i.into())?;
125        assert!(region.start() == 0);
126        assert!(region.len() == 10);
127        assert!(region.reserved() == PAGE_SIZE * 2);
128        // We only punch a hole in whole pages (4096 bytes)
129        // Thus the last byte of the page where the is still data wasn't overwritten when truncating
130        // And the first byte of the punched page was set to 0
131        assert!(database.mmap()[4095..=4096] == [1, 0]);
132    }
133
134    database.flush()?;
135    println!("Disk usage - post trunc: {}", database.disk_usage());
136
137    database.remove_region(region1_i.into())?;
138
139    database.flush()?;
140
141    println!("Disk usage - post remove: {}", database.disk_usage());
142
143    {
144        let regions = database.regions();
145        let index_to_region = regions.index_to_region();
146        assert!(index_to_region.len() == 1);
147        assert!(index_to_region[0].is_none());
148        assert!(regions.id_to_index().is_empty());
149
150        let layout = database.layout();
151        assert!(layout.start_to_index().is_empty());
152        assert!(layout.start_to_hole().len() == 1);
153    }
154
155    let (region1_i, _) = database.create_region_if_needed("region1")?;
156    let (region2_i, _) = database.create_region_if_needed("region2")?;
157    let (region3_i, _) = database.create_region_if_needed("region3")?;
158
159    // dbg!(seqdb.layout());
160
161    {
162        let regions = database.regions();
163        let index_to_region = regions.index_to_region();
164        assert!(index_to_region.len() == 3);
165        let region1 = database.get_region(region1_i.into())?;
166        assert!(region1.start() == 0);
167        assert!(region1.len() == 0);
168        assert!(region1.reserved() == PAGE_SIZE);
169        let region2 = database.get_region(region2_i.into())?;
170        assert!(region2.start() == PAGE_SIZE);
171        assert!(region2.len() == 0);
172        assert!(region2.reserved() == PAGE_SIZE);
173        let region3 = database.get_region(region3_i.into())?;
174        assert!(region3.start() == PAGE_SIZE * 2);
175        assert!(region3.len() == 0);
176        assert!(region3.reserved() == PAGE_SIZE);
177        let id_to_index = regions.id_to_index();
178        assert!(id_to_index.len() == 3);
179        assert!(id_to_index.get("region1") == Some(&0));
180        assert!(id_to_index.get("region2") == Some(&1));
181        assert!(id_to_index.get("region3") == Some(&2));
182
183        let layout = database.layout();
184        let start_to_index = layout.start_to_index();
185        assert!(start_to_index.len() == 3);
186        assert!(start_to_index.get(&0) == Some(&0));
187        assert!(start_to_index.get(&PAGE_SIZE) == Some(&1));
188        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&2));
189        assert!(layout.start_to_hole().is_empty());
190    }
191
192    database.remove_region(region2_i.into())?;
193
194    {
195        let regions = database.regions();
196        let index_to_region = regions.index_to_region();
197        assert!(index_to_region.len() == 3);
198        let region1 = database.get_region(region1_i.into())?;
199        assert!(region1.start() == 0);
200        assert!(region1.len() == 0);
201        assert!(region1.reserved() == PAGE_SIZE);
202        assert!(database.get_region(region2_i.into()).is_err());
203        assert!(
204            index_to_region
205                .get(region2_i)
206                .is_some_and(|opt| opt.is_none())
207        );
208        let region3 = database.get_region(region3_i.into())?;
209        assert!(region3.start() == PAGE_SIZE * 2);
210        assert!(region3.len() == 0);
211        assert!(region3.reserved() == PAGE_SIZE);
212        let id_to_index = regions.id_to_index();
213        assert!(id_to_index.len() == 2);
214        assert!(id_to_index.get("region1") == Some(&0));
215        assert!(id_to_index.get("region2").is_none());
216        assert!(id_to_index.get("region3") == Some(&2));
217
218        let layout = database.layout();
219        let start_to_index = layout.start_to_index();
220        assert!(start_to_index.len() == 2);
221        assert!(start_to_index.get(&0) == Some(&region1_i));
222        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
223        let start_to_hole = layout.start_to_hole();
224        assert!(start_to_hole.len() == 1);
225        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
226
227        drop(regions);
228        drop(layout);
229        assert!(
230            database
231                .remove_region(region2_i.into())
232                .is_ok_and(|o| o.is_none())
233        );
234    }
235
236    let (region2_i, _) = database.create_region_if_needed("region2")?;
237
238    {
239        assert!(region2_i == 1)
240    }
241
242    database.remove_region(region2_i.into())?;
243
244    {
245        let regions = database.regions();
246        let index_to_region = regions.index_to_region();
247        assert!(index_to_region.len() == 3);
248        let region1 = database.get_region(region1_i.into())?;
249        assert!(region1.start() == 0);
250        assert!(region1.len() == 0);
251        assert!(region1.reserved() == PAGE_SIZE);
252        assert!(database.get_region(region2_i.into()).is_err());
253        assert!(
254            index_to_region
255                .get(region2_i)
256                .is_some_and(|opt| opt.is_none())
257        );
258        let region3 = database.get_region(region3_i.into())?;
259        assert!(region3.start() == PAGE_SIZE * 2);
260        assert!(region3.len() == 0);
261        assert!(region3.reserved() == PAGE_SIZE);
262        let id_to_index = regions.id_to_index();
263        assert!(id_to_index.len() == 2);
264        assert!(id_to_index.get("region1") == Some(&0));
265        assert!(id_to_index.get("region2").is_none());
266        assert!(id_to_index.get("region3") == Some(&2));
267
268        let layout = database.layout();
269        let start_to_index = layout.start_to_index();
270        assert!(start_to_index.len() == 2);
271        assert!(start_to_index.get(&0) == Some(&region1_i));
272        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
273        let start_to_hole = layout.start_to_hole();
274        assert!(start_to_hole.len() == 1);
275        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
276
277        drop(regions);
278        drop(layout);
279        assert!(
280            database
281                .remove_region(region2_i.into())
282                .is_ok_and(|o| o.is_none())
283        );
284    }
285
286    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
287
288    {
289        let regions = database.regions();
290        let index_to_region = regions.index_to_region();
291        assert!(index_to_region.len() == 3);
292        let region1 = database.get_region(region1_i.into())?;
293        assert!(region1.start() == 0);
294        assert!(region1.len() == 8000);
295        assert!(region1.reserved() == 2 * PAGE_SIZE);
296        assert!(database.get_region(region2_i.into()).is_err());
297        assert!(
298            index_to_region
299                .get(region2_i)
300                .is_some_and(|opt| opt.is_none())
301        );
302        let region3 = database.get_region(region3_i.into())?;
303        assert!(region3.start() == PAGE_SIZE * 2);
304        assert!(region3.len() == 0);
305        assert!(region3.reserved() == PAGE_SIZE);
306        let id_to_index = regions.id_to_index();
307        assert!(id_to_index.len() == 2);
308        assert!(id_to_index.get("region1") == Some(&0));
309        assert!(id_to_index.get("region2").is_none());
310        assert!(id_to_index.get("region3") == Some(&2));
311
312        let layout = database.layout();
313        let start_to_index = layout.start_to_index();
314        assert!(start_to_index.len() == 2);
315        assert!(start_to_index.get(&0) == Some(&region1_i));
316        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
317        let start_to_hole = layout.start_to_hole();
318        assert!(start_to_hole.is_empty());
319    }
320
321    let (region2_i, _) = database.create_region_if_needed("region2")?;
322
323    {
324        let regions = database.regions();
325        let index_to_region = regions.index_to_region();
326        assert!(index_to_region.len() == 3);
327        let region1 = database.get_region(region1_i.into())?;
328        assert!(region1.start() == 0);
329        assert!(region1.len() == 8000);
330        assert!(region1.reserved() == 2 * PAGE_SIZE);
331        let region2 = database.get_region(region2_i.into())?;
332        assert!(region2.start() == PAGE_SIZE * 3);
333        assert!(region2.len() == 0);
334        assert!(region2.reserved() == PAGE_SIZE);
335        let region3 = database.get_region(region3_i.into())?;
336        assert!(region3.start() == PAGE_SIZE * 2);
337        assert!(region3.len() == 0);
338        assert!(region3.reserved() == PAGE_SIZE);
339        let id_to_index = regions.id_to_index();
340        assert!(id_to_index.len() == 3);
341        assert!(id_to_index.get("region1") == Some(&0));
342        assert!(id_to_index.get("region2") == Some(&1));
343        assert!(id_to_index.get("region3") == Some(&2));
344
345        let layout = database.layout();
346        let start_to_index = layout.start_to_index();
347        assert!(start_to_index.len() == 3);
348        assert!(start_to_index.get(&0) == Some(&region1_i));
349        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
350        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
351        let start_to_hole = layout.start_to_hole();
352        assert!(start_to_hole.is_empty());
353    }
354
355    database.remove_region(region3_i.into())?;
356
357    {
358        let regions = database.regions();
359        let index_to_region = regions.index_to_region();
360        assert!(index_to_region.len() == 3);
361        let region1 = database.get_region(region1_i.into())?;
362        assert!(region1.start() == 0);
363        assert!(region1.len() == 8000);
364        assert!(region1.reserved() == 2 * PAGE_SIZE);
365        let region2 = database.get_region(region2_i.into())?;
366        assert!(region2.start() == PAGE_SIZE * 3);
367        assert!(region2.len() == 0);
368        assert!(region2.reserved() == PAGE_SIZE);
369        assert!(database.get_region(region3_i.into()).is_err());
370        let id_to_index = regions.id_to_index();
371        assert!(id_to_index.len() == 2);
372        assert!(id_to_index.get("region1") == Some(&0));
373        assert!(id_to_index.get("region2") == Some(&1));
374        assert!(id_to_index.get("region3").is_none());
375
376        let layout = database.layout();
377        let start_to_index = layout.start_to_index();
378        assert!(start_to_index.len() == 2);
379        assert!(start_to_index.get(&0) == Some(&region1_i));
380        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
381        let start_to_hole = layout.start_to_hole();
382        assert!(start_to_hole.get(&(PAGE_SIZE * 2)) == Some(&PAGE_SIZE));
383    }
384
385    database.write_all_to_region(region1_i.into(), &[1; 8000])?;
386
387    {
388        let regions = database.regions();
389        let index_to_region = regions.index_to_region();
390        assert!(index_to_region.len() == 3);
391        let region1 = database.get_region(region1_i.into())?;
392        assert!(region1.start() == PAGE_SIZE * 4);
393        assert!(region1.len() == 16_000);
394        assert!(region1.reserved() == 4 * PAGE_SIZE);
395        let region2 = database.get_region(region2_i.into())?;
396        assert!(region2.start() == PAGE_SIZE * 3);
397        assert!(region2.len() == 0);
398        assert!(region2.reserved() == PAGE_SIZE);
399        assert!(database.get_region(region3_i.into()).is_err());
400        let id_to_index = regions.id_to_index();
401        assert!(id_to_index.len() == 2);
402        assert!(id_to_index.get("region1") == Some(&0));
403        assert!(id_to_index.get("region2") == Some(&1));
404        assert!(id_to_index.get("region3").is_none());
405
406        let layout = database.layout();
407        let start_to_index = layout.start_to_index();
408        assert!(start_to_index.len() == 2);
409        assert!(start_to_index.get(&(PAGE_SIZE * 4)) == Some(&region1_i));
410        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
411        let start_to_hole = layout.start_to_hole();
412        assert!(start_to_hole.get(&0) == Some(&(PAGE_SIZE * 3)));
413    }
414
415    database.write_all_to_region(region2_i.into(), &[1; 6000])?;
416
417    let (region4_i, _) = database.create_region_if_needed("region4")?;
418    database.remove_region(region2_i.into())?;
419    database.remove_region(region4_i.into())?;
420
421    let regions = database.regions();
422    dbg!(&regions);
423    let layout = database.layout();
424    dbg!(&layout);
425
426    Ok(())
427}
Source

pub fn remove_region( &self, identifier: Identifier, ) -> Result<Option<Arc<RwLock<Region>>>>

Examples found in repository?
examples/db.rs (line 137)
5fn main() -> Result<()> {
6    let _ = fs::remove_dir_all("vecs");
7
8    let database = Database::open(Path::new("vecs"))?;
9
10    // let seqdb_min_len = PAGE_SIZE * 1_000_000;
11    // let min_regions = 20_000;
12
13    // seqdb.set_min_len(seqdb_min_len)?;
14    // seqdb.set_min_regions(min_regions)?;
15
16    let (region1_i, _) = database.create_region_if_needed("region1")?;
17
18    {
19        let layout = database.layout();
20        assert!(layout.start_to_index().len() == 1);
21        assert!(layout.start_to_index().first_key_value() == Some((&0, &0)));
22        assert!(layout.start_to_hole().is_empty());
23
24        let regions = database.regions();
25        assert!(
26            regions
27                .get_region_index_from_id("region1")
28                .is_some_and(|i| i == region1_i)
29        );
30
31        let region = database.get_region(region1_i.into())?;
32        assert!(region.start() == 0);
33        assert!(region.len() == 0);
34        assert!(region.reserved() == PAGE_SIZE);
35    }
36
37    database.write_all_to_region(region1_i.into(), &[0, 1, 2, 3, 4])?;
38
39    {
40        let region = database.get_region(region1_i.into())?;
41        assert!(region.start() == 0);
42        assert!(region.len() == 5);
43        assert!(region.reserved() == PAGE_SIZE);
44
45        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
46    }
47
48    database.write_all_to_region(region1_i.into(), &[5, 6, 7, 8, 9])?;
49
50    {
51        let region = database.get_region(region1_i.into())?;
52        assert!(region.start() == 0);
53        assert!(region.len() == 10);
54        assert!(region.reserved() == PAGE_SIZE);
55
56        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
57    }
58
59    database.write_all_to_region_at(region1_i.into(), &[1, 2], 0)?;
60
61    {
62        let region = database.get_region(region1_i.into())?;
63        assert!(region.start() == 0);
64        assert!(region.len() == 10);
65        assert!(region.reserved() == PAGE_SIZE);
66
67        assert!(database.mmap()[0..10] == [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]);
68    }
69
70    database.write_all_to_region_at(region1_i.into(), &[10, 11, 12, 13, 14, 15, 16, 17, 18], 4)?;
71
72    {
73        let region = database.get_region(region1_i.into())?;
74        assert!(region.start() == 0);
75        assert!(region.len() == 13);
76        assert!(region.reserved() == PAGE_SIZE);
77
78        assert!(
79            database.mmap()[0..20]
80                == [
81                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0
82                ]
83        );
84    }
85
86    database.write_all_to_region_at(region1_i.into(), &[0, 0, 0, 0, 0, 1], 13)?;
87
88    {
89        let region = database.get_region(region1_i.into())?;
90        assert!(region.start() == 0);
91        assert!(region.len() == 19);
92        assert!(region.reserved() == PAGE_SIZE);
93
94        assert!(
95            database.mmap()[0..20]
96                == [
97                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 1, 0
98                ]
99        );
100    }
101
102    dbg!(1);
103
104    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
105
106    {
107        let region = database.get_region(region1_i.into())?;
108        assert!(region.start() == 0);
109        assert!(region.len() == 8000);
110        assert!(region.reserved() == PAGE_SIZE * 2);
111
112        assert!(database.mmap()[0..8000] == [1; 8000]);
113        assert!(database.mmap()[8000..8001] == [0]);
114    }
115
116    println!("Disk usage - pre sync: {}", database.disk_usage());
117    database.flush()?;
118    println!("Disk usage - post sync: {}", database.disk_usage());
119
120    database.truncate_region(region1_i.into(), 10)?;
121    database.punch_holes()?;
122
123    {
124        let region = database.get_region(region1_i.into())?;
125        assert!(region.start() == 0);
126        assert!(region.len() == 10);
127        assert!(region.reserved() == PAGE_SIZE * 2);
128        // We only punch a hole in whole pages (4096 bytes)
129        // Thus the last byte of the page where the is still data wasn't overwritten when truncating
130        // And the first byte of the punched page was set to 0
131        assert!(database.mmap()[4095..=4096] == [1, 0]);
132    }
133
134    database.flush()?;
135    println!("Disk usage - post trunc: {}", database.disk_usage());
136
137    database.remove_region(region1_i.into())?;
138
139    database.flush()?;
140
141    println!("Disk usage - post remove: {}", database.disk_usage());
142
143    {
144        let regions = database.regions();
145        let index_to_region = regions.index_to_region();
146        assert!(index_to_region.len() == 1);
147        assert!(index_to_region[0].is_none());
148        assert!(regions.id_to_index().is_empty());
149
150        let layout = database.layout();
151        assert!(layout.start_to_index().is_empty());
152        assert!(layout.start_to_hole().len() == 1);
153    }
154
155    let (region1_i, _) = database.create_region_if_needed("region1")?;
156    let (region2_i, _) = database.create_region_if_needed("region2")?;
157    let (region3_i, _) = database.create_region_if_needed("region3")?;
158
159    // dbg!(seqdb.layout());
160
161    {
162        let regions = database.regions();
163        let index_to_region = regions.index_to_region();
164        assert!(index_to_region.len() == 3);
165        let region1 = database.get_region(region1_i.into())?;
166        assert!(region1.start() == 0);
167        assert!(region1.len() == 0);
168        assert!(region1.reserved() == PAGE_SIZE);
169        let region2 = database.get_region(region2_i.into())?;
170        assert!(region2.start() == PAGE_SIZE);
171        assert!(region2.len() == 0);
172        assert!(region2.reserved() == PAGE_SIZE);
173        let region3 = database.get_region(region3_i.into())?;
174        assert!(region3.start() == PAGE_SIZE * 2);
175        assert!(region3.len() == 0);
176        assert!(region3.reserved() == PAGE_SIZE);
177        let id_to_index = regions.id_to_index();
178        assert!(id_to_index.len() == 3);
179        assert!(id_to_index.get("region1") == Some(&0));
180        assert!(id_to_index.get("region2") == Some(&1));
181        assert!(id_to_index.get("region3") == Some(&2));
182
183        let layout = database.layout();
184        let start_to_index = layout.start_to_index();
185        assert!(start_to_index.len() == 3);
186        assert!(start_to_index.get(&0) == Some(&0));
187        assert!(start_to_index.get(&PAGE_SIZE) == Some(&1));
188        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&2));
189        assert!(layout.start_to_hole().is_empty());
190    }
191
192    database.remove_region(region2_i.into())?;
193
194    {
195        let regions = database.regions();
196        let index_to_region = regions.index_to_region();
197        assert!(index_to_region.len() == 3);
198        let region1 = database.get_region(region1_i.into())?;
199        assert!(region1.start() == 0);
200        assert!(region1.len() == 0);
201        assert!(region1.reserved() == PAGE_SIZE);
202        assert!(database.get_region(region2_i.into()).is_err());
203        assert!(
204            index_to_region
205                .get(region2_i)
206                .is_some_and(|opt| opt.is_none())
207        );
208        let region3 = database.get_region(region3_i.into())?;
209        assert!(region3.start() == PAGE_SIZE * 2);
210        assert!(region3.len() == 0);
211        assert!(region3.reserved() == PAGE_SIZE);
212        let id_to_index = regions.id_to_index();
213        assert!(id_to_index.len() == 2);
214        assert!(id_to_index.get("region1") == Some(&0));
215        assert!(id_to_index.get("region2").is_none());
216        assert!(id_to_index.get("region3") == Some(&2));
217
218        let layout = database.layout();
219        let start_to_index = layout.start_to_index();
220        assert!(start_to_index.len() == 2);
221        assert!(start_to_index.get(&0) == Some(&region1_i));
222        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
223        let start_to_hole = layout.start_to_hole();
224        assert!(start_to_hole.len() == 1);
225        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
226
227        drop(regions);
228        drop(layout);
229        assert!(
230            database
231                .remove_region(region2_i.into())
232                .is_ok_and(|o| o.is_none())
233        );
234    }
235
236    let (region2_i, _) = database.create_region_if_needed("region2")?;
237
238    {
239        assert!(region2_i == 1)
240    }
241
242    database.remove_region(region2_i.into())?;
243
244    {
245        let regions = database.regions();
246        let index_to_region = regions.index_to_region();
247        assert!(index_to_region.len() == 3);
248        let region1 = database.get_region(region1_i.into())?;
249        assert!(region1.start() == 0);
250        assert!(region1.len() == 0);
251        assert!(region1.reserved() == PAGE_SIZE);
252        assert!(database.get_region(region2_i.into()).is_err());
253        assert!(
254            index_to_region
255                .get(region2_i)
256                .is_some_and(|opt| opt.is_none())
257        );
258        let region3 = database.get_region(region3_i.into())?;
259        assert!(region3.start() == PAGE_SIZE * 2);
260        assert!(region3.len() == 0);
261        assert!(region3.reserved() == PAGE_SIZE);
262        let id_to_index = regions.id_to_index();
263        assert!(id_to_index.len() == 2);
264        assert!(id_to_index.get("region1") == Some(&0));
265        assert!(id_to_index.get("region2").is_none());
266        assert!(id_to_index.get("region3") == Some(&2));
267
268        let layout = database.layout();
269        let start_to_index = layout.start_to_index();
270        assert!(start_to_index.len() == 2);
271        assert!(start_to_index.get(&0) == Some(&region1_i));
272        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
273        let start_to_hole = layout.start_to_hole();
274        assert!(start_to_hole.len() == 1);
275        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
276
277        drop(regions);
278        drop(layout);
279        assert!(
280            database
281                .remove_region(region2_i.into())
282                .is_ok_and(|o| o.is_none())
283        );
284    }
285
286    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
287
288    {
289        let regions = database.regions();
290        let index_to_region = regions.index_to_region();
291        assert!(index_to_region.len() == 3);
292        let region1 = database.get_region(region1_i.into())?;
293        assert!(region1.start() == 0);
294        assert!(region1.len() == 8000);
295        assert!(region1.reserved() == 2 * PAGE_SIZE);
296        assert!(database.get_region(region2_i.into()).is_err());
297        assert!(
298            index_to_region
299                .get(region2_i)
300                .is_some_and(|opt| opt.is_none())
301        );
302        let region3 = database.get_region(region3_i.into())?;
303        assert!(region3.start() == PAGE_SIZE * 2);
304        assert!(region3.len() == 0);
305        assert!(region3.reserved() == PAGE_SIZE);
306        let id_to_index = regions.id_to_index();
307        assert!(id_to_index.len() == 2);
308        assert!(id_to_index.get("region1") == Some(&0));
309        assert!(id_to_index.get("region2").is_none());
310        assert!(id_to_index.get("region3") == Some(&2));
311
312        let layout = database.layout();
313        let start_to_index = layout.start_to_index();
314        assert!(start_to_index.len() == 2);
315        assert!(start_to_index.get(&0) == Some(&region1_i));
316        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
317        let start_to_hole = layout.start_to_hole();
318        assert!(start_to_hole.is_empty());
319    }
320
321    let (region2_i, _) = database.create_region_if_needed("region2")?;
322
323    {
324        let regions = database.regions();
325        let index_to_region = regions.index_to_region();
326        assert!(index_to_region.len() == 3);
327        let region1 = database.get_region(region1_i.into())?;
328        assert!(region1.start() == 0);
329        assert!(region1.len() == 8000);
330        assert!(region1.reserved() == 2 * PAGE_SIZE);
331        let region2 = database.get_region(region2_i.into())?;
332        assert!(region2.start() == PAGE_SIZE * 3);
333        assert!(region2.len() == 0);
334        assert!(region2.reserved() == PAGE_SIZE);
335        let region3 = database.get_region(region3_i.into())?;
336        assert!(region3.start() == PAGE_SIZE * 2);
337        assert!(region3.len() == 0);
338        assert!(region3.reserved() == PAGE_SIZE);
339        let id_to_index = regions.id_to_index();
340        assert!(id_to_index.len() == 3);
341        assert!(id_to_index.get("region1") == Some(&0));
342        assert!(id_to_index.get("region2") == Some(&1));
343        assert!(id_to_index.get("region3") == Some(&2));
344
345        let layout = database.layout();
346        let start_to_index = layout.start_to_index();
347        assert!(start_to_index.len() == 3);
348        assert!(start_to_index.get(&0) == Some(&region1_i));
349        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
350        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
351        let start_to_hole = layout.start_to_hole();
352        assert!(start_to_hole.is_empty());
353    }
354
355    database.remove_region(region3_i.into())?;
356
357    {
358        let regions = database.regions();
359        let index_to_region = regions.index_to_region();
360        assert!(index_to_region.len() == 3);
361        let region1 = database.get_region(region1_i.into())?;
362        assert!(region1.start() == 0);
363        assert!(region1.len() == 8000);
364        assert!(region1.reserved() == 2 * PAGE_SIZE);
365        let region2 = database.get_region(region2_i.into())?;
366        assert!(region2.start() == PAGE_SIZE * 3);
367        assert!(region2.len() == 0);
368        assert!(region2.reserved() == PAGE_SIZE);
369        assert!(database.get_region(region3_i.into()).is_err());
370        let id_to_index = regions.id_to_index();
371        assert!(id_to_index.len() == 2);
372        assert!(id_to_index.get("region1") == Some(&0));
373        assert!(id_to_index.get("region2") == Some(&1));
374        assert!(id_to_index.get("region3").is_none());
375
376        let layout = database.layout();
377        let start_to_index = layout.start_to_index();
378        assert!(start_to_index.len() == 2);
379        assert!(start_to_index.get(&0) == Some(&region1_i));
380        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
381        let start_to_hole = layout.start_to_hole();
382        assert!(start_to_hole.get(&(PAGE_SIZE * 2)) == Some(&PAGE_SIZE));
383    }
384
385    database.write_all_to_region(region1_i.into(), &[1; 8000])?;
386
387    {
388        let regions = database.regions();
389        let index_to_region = regions.index_to_region();
390        assert!(index_to_region.len() == 3);
391        let region1 = database.get_region(region1_i.into())?;
392        assert!(region1.start() == PAGE_SIZE * 4);
393        assert!(region1.len() == 16_000);
394        assert!(region1.reserved() == 4 * PAGE_SIZE);
395        let region2 = database.get_region(region2_i.into())?;
396        assert!(region2.start() == PAGE_SIZE * 3);
397        assert!(region2.len() == 0);
398        assert!(region2.reserved() == PAGE_SIZE);
399        assert!(database.get_region(region3_i.into()).is_err());
400        let id_to_index = regions.id_to_index();
401        assert!(id_to_index.len() == 2);
402        assert!(id_to_index.get("region1") == Some(&0));
403        assert!(id_to_index.get("region2") == Some(&1));
404        assert!(id_to_index.get("region3").is_none());
405
406        let layout = database.layout();
407        let start_to_index = layout.start_to_index();
408        assert!(start_to_index.len() == 2);
409        assert!(start_to_index.get(&(PAGE_SIZE * 4)) == Some(&region1_i));
410        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
411        let start_to_hole = layout.start_to_hole();
412        assert!(start_to_hole.get(&0) == Some(&(PAGE_SIZE * 3)));
413    }
414
415    database.write_all_to_region(region2_i.into(), &[1; 6000])?;
416
417    let (region4_i, _) = database.create_region_if_needed("region4")?;
418    database.remove_region(region2_i.into())?;
419    database.remove_region(region4_i.into())?;
420
421    let regions = database.regions();
422    dbg!(&regions);
423    let layout = database.layout();
424    dbg!(&layout);
425
426    Ok(())
427}
Source

pub fn regions(&self) -> RwLockReadGuard<'_, Regions>

Examples found in repository?
examples/db.rs (line 24)
5fn main() -> Result<()> {
6    let _ = fs::remove_dir_all("vecs");
7
8    let database = Database::open(Path::new("vecs"))?;
9
10    // let seqdb_min_len = PAGE_SIZE * 1_000_000;
11    // let min_regions = 20_000;
12
13    // seqdb.set_min_len(seqdb_min_len)?;
14    // seqdb.set_min_regions(min_regions)?;
15
16    let (region1_i, _) = database.create_region_if_needed("region1")?;
17
18    {
19        let layout = database.layout();
20        assert!(layout.start_to_index().len() == 1);
21        assert!(layout.start_to_index().first_key_value() == Some((&0, &0)));
22        assert!(layout.start_to_hole().is_empty());
23
24        let regions = database.regions();
25        assert!(
26            regions
27                .get_region_index_from_id("region1")
28                .is_some_and(|i| i == region1_i)
29        );
30
31        let region = database.get_region(region1_i.into())?;
32        assert!(region.start() == 0);
33        assert!(region.len() == 0);
34        assert!(region.reserved() == PAGE_SIZE);
35    }
36
37    database.write_all_to_region(region1_i.into(), &[0, 1, 2, 3, 4])?;
38
39    {
40        let region = database.get_region(region1_i.into())?;
41        assert!(region.start() == 0);
42        assert!(region.len() == 5);
43        assert!(region.reserved() == PAGE_SIZE);
44
45        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
46    }
47
48    database.write_all_to_region(region1_i.into(), &[5, 6, 7, 8, 9])?;
49
50    {
51        let region = database.get_region(region1_i.into())?;
52        assert!(region.start() == 0);
53        assert!(region.len() == 10);
54        assert!(region.reserved() == PAGE_SIZE);
55
56        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
57    }
58
59    database.write_all_to_region_at(region1_i.into(), &[1, 2], 0)?;
60
61    {
62        let region = database.get_region(region1_i.into())?;
63        assert!(region.start() == 0);
64        assert!(region.len() == 10);
65        assert!(region.reserved() == PAGE_SIZE);
66
67        assert!(database.mmap()[0..10] == [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]);
68    }
69
70    database.write_all_to_region_at(region1_i.into(), &[10, 11, 12, 13, 14, 15, 16, 17, 18], 4)?;
71
72    {
73        let region = database.get_region(region1_i.into())?;
74        assert!(region.start() == 0);
75        assert!(region.len() == 13);
76        assert!(region.reserved() == PAGE_SIZE);
77
78        assert!(
79            database.mmap()[0..20]
80                == [
81                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0
82                ]
83        );
84    }
85
86    database.write_all_to_region_at(region1_i.into(), &[0, 0, 0, 0, 0, 1], 13)?;
87
88    {
89        let region = database.get_region(region1_i.into())?;
90        assert!(region.start() == 0);
91        assert!(region.len() == 19);
92        assert!(region.reserved() == PAGE_SIZE);
93
94        assert!(
95            database.mmap()[0..20]
96                == [
97                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 1, 0
98                ]
99        );
100    }
101
102    dbg!(1);
103
104    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
105
106    {
107        let region = database.get_region(region1_i.into())?;
108        assert!(region.start() == 0);
109        assert!(region.len() == 8000);
110        assert!(region.reserved() == PAGE_SIZE * 2);
111
112        assert!(database.mmap()[0..8000] == [1; 8000]);
113        assert!(database.mmap()[8000..8001] == [0]);
114    }
115
116    println!("Disk usage - pre sync: {}", database.disk_usage());
117    database.flush()?;
118    println!("Disk usage - post sync: {}", database.disk_usage());
119
120    database.truncate_region(region1_i.into(), 10)?;
121    database.punch_holes()?;
122
123    {
124        let region = database.get_region(region1_i.into())?;
125        assert!(region.start() == 0);
126        assert!(region.len() == 10);
127        assert!(region.reserved() == PAGE_SIZE * 2);
128        // We only punch a hole in whole pages (4096 bytes)
129        // Thus the last byte of the page where the is still data wasn't overwritten when truncating
130        // And the first byte of the punched page was set to 0
131        assert!(database.mmap()[4095..=4096] == [1, 0]);
132    }
133
134    database.flush()?;
135    println!("Disk usage - post trunc: {}", database.disk_usage());
136
137    database.remove_region(region1_i.into())?;
138
139    database.flush()?;
140
141    println!("Disk usage - post remove: {}", database.disk_usage());
142
143    {
144        let regions = database.regions();
145        let index_to_region = regions.index_to_region();
146        assert!(index_to_region.len() == 1);
147        assert!(index_to_region[0].is_none());
148        assert!(regions.id_to_index().is_empty());
149
150        let layout = database.layout();
151        assert!(layout.start_to_index().is_empty());
152        assert!(layout.start_to_hole().len() == 1);
153    }
154
155    let (region1_i, _) = database.create_region_if_needed("region1")?;
156    let (region2_i, _) = database.create_region_if_needed("region2")?;
157    let (region3_i, _) = database.create_region_if_needed("region3")?;
158
159    // dbg!(seqdb.layout());
160
161    {
162        let regions = database.regions();
163        let index_to_region = regions.index_to_region();
164        assert!(index_to_region.len() == 3);
165        let region1 = database.get_region(region1_i.into())?;
166        assert!(region1.start() == 0);
167        assert!(region1.len() == 0);
168        assert!(region1.reserved() == PAGE_SIZE);
169        let region2 = database.get_region(region2_i.into())?;
170        assert!(region2.start() == PAGE_SIZE);
171        assert!(region2.len() == 0);
172        assert!(region2.reserved() == PAGE_SIZE);
173        let region3 = database.get_region(region3_i.into())?;
174        assert!(region3.start() == PAGE_SIZE * 2);
175        assert!(region3.len() == 0);
176        assert!(region3.reserved() == PAGE_SIZE);
177        let id_to_index = regions.id_to_index();
178        assert!(id_to_index.len() == 3);
179        assert!(id_to_index.get("region1") == Some(&0));
180        assert!(id_to_index.get("region2") == Some(&1));
181        assert!(id_to_index.get("region3") == Some(&2));
182
183        let layout = database.layout();
184        let start_to_index = layout.start_to_index();
185        assert!(start_to_index.len() == 3);
186        assert!(start_to_index.get(&0) == Some(&0));
187        assert!(start_to_index.get(&PAGE_SIZE) == Some(&1));
188        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&2));
189        assert!(layout.start_to_hole().is_empty());
190    }
191
192    database.remove_region(region2_i.into())?;
193
194    {
195        let regions = database.regions();
196        let index_to_region = regions.index_to_region();
197        assert!(index_to_region.len() == 3);
198        let region1 = database.get_region(region1_i.into())?;
199        assert!(region1.start() == 0);
200        assert!(region1.len() == 0);
201        assert!(region1.reserved() == PAGE_SIZE);
202        assert!(database.get_region(region2_i.into()).is_err());
203        assert!(
204            index_to_region
205                .get(region2_i)
206                .is_some_and(|opt| opt.is_none())
207        );
208        let region3 = database.get_region(region3_i.into())?;
209        assert!(region3.start() == PAGE_SIZE * 2);
210        assert!(region3.len() == 0);
211        assert!(region3.reserved() == PAGE_SIZE);
212        let id_to_index = regions.id_to_index();
213        assert!(id_to_index.len() == 2);
214        assert!(id_to_index.get("region1") == Some(&0));
215        assert!(id_to_index.get("region2").is_none());
216        assert!(id_to_index.get("region3") == Some(&2));
217
218        let layout = database.layout();
219        let start_to_index = layout.start_to_index();
220        assert!(start_to_index.len() == 2);
221        assert!(start_to_index.get(&0) == Some(&region1_i));
222        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
223        let start_to_hole = layout.start_to_hole();
224        assert!(start_to_hole.len() == 1);
225        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
226
227        drop(regions);
228        drop(layout);
229        assert!(
230            database
231                .remove_region(region2_i.into())
232                .is_ok_and(|o| o.is_none())
233        );
234    }
235
236    let (region2_i, _) = database.create_region_if_needed("region2")?;
237
238    {
239        assert!(region2_i == 1)
240    }
241
242    database.remove_region(region2_i.into())?;
243
244    {
245        let regions = database.regions();
246        let index_to_region = regions.index_to_region();
247        assert!(index_to_region.len() == 3);
248        let region1 = database.get_region(region1_i.into())?;
249        assert!(region1.start() == 0);
250        assert!(region1.len() == 0);
251        assert!(region1.reserved() == PAGE_SIZE);
252        assert!(database.get_region(region2_i.into()).is_err());
253        assert!(
254            index_to_region
255                .get(region2_i)
256                .is_some_and(|opt| opt.is_none())
257        );
258        let region3 = database.get_region(region3_i.into())?;
259        assert!(region3.start() == PAGE_SIZE * 2);
260        assert!(region3.len() == 0);
261        assert!(region3.reserved() == PAGE_SIZE);
262        let id_to_index = regions.id_to_index();
263        assert!(id_to_index.len() == 2);
264        assert!(id_to_index.get("region1") == Some(&0));
265        assert!(id_to_index.get("region2").is_none());
266        assert!(id_to_index.get("region3") == Some(&2));
267
268        let layout = database.layout();
269        let start_to_index = layout.start_to_index();
270        assert!(start_to_index.len() == 2);
271        assert!(start_to_index.get(&0) == Some(&region1_i));
272        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
273        let start_to_hole = layout.start_to_hole();
274        assert!(start_to_hole.len() == 1);
275        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
276
277        drop(regions);
278        drop(layout);
279        assert!(
280            database
281                .remove_region(region2_i.into())
282                .is_ok_and(|o| o.is_none())
283        );
284    }
285
286    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
287
288    {
289        let regions = database.regions();
290        let index_to_region = regions.index_to_region();
291        assert!(index_to_region.len() == 3);
292        let region1 = database.get_region(region1_i.into())?;
293        assert!(region1.start() == 0);
294        assert!(region1.len() == 8000);
295        assert!(region1.reserved() == 2 * PAGE_SIZE);
296        assert!(database.get_region(region2_i.into()).is_err());
297        assert!(
298            index_to_region
299                .get(region2_i)
300                .is_some_and(|opt| opt.is_none())
301        );
302        let region3 = database.get_region(region3_i.into())?;
303        assert!(region3.start() == PAGE_SIZE * 2);
304        assert!(region3.len() == 0);
305        assert!(region3.reserved() == PAGE_SIZE);
306        let id_to_index = regions.id_to_index();
307        assert!(id_to_index.len() == 2);
308        assert!(id_to_index.get("region1") == Some(&0));
309        assert!(id_to_index.get("region2").is_none());
310        assert!(id_to_index.get("region3") == Some(&2));
311
312        let layout = database.layout();
313        let start_to_index = layout.start_to_index();
314        assert!(start_to_index.len() == 2);
315        assert!(start_to_index.get(&0) == Some(&region1_i));
316        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
317        let start_to_hole = layout.start_to_hole();
318        assert!(start_to_hole.is_empty());
319    }
320
321    let (region2_i, _) = database.create_region_if_needed("region2")?;
322
323    {
324        let regions = database.regions();
325        let index_to_region = regions.index_to_region();
326        assert!(index_to_region.len() == 3);
327        let region1 = database.get_region(region1_i.into())?;
328        assert!(region1.start() == 0);
329        assert!(region1.len() == 8000);
330        assert!(region1.reserved() == 2 * PAGE_SIZE);
331        let region2 = database.get_region(region2_i.into())?;
332        assert!(region2.start() == PAGE_SIZE * 3);
333        assert!(region2.len() == 0);
334        assert!(region2.reserved() == PAGE_SIZE);
335        let region3 = database.get_region(region3_i.into())?;
336        assert!(region3.start() == PAGE_SIZE * 2);
337        assert!(region3.len() == 0);
338        assert!(region3.reserved() == PAGE_SIZE);
339        let id_to_index = regions.id_to_index();
340        assert!(id_to_index.len() == 3);
341        assert!(id_to_index.get("region1") == Some(&0));
342        assert!(id_to_index.get("region2") == Some(&1));
343        assert!(id_to_index.get("region3") == Some(&2));
344
345        let layout = database.layout();
346        let start_to_index = layout.start_to_index();
347        assert!(start_to_index.len() == 3);
348        assert!(start_to_index.get(&0) == Some(&region1_i));
349        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
350        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
351        let start_to_hole = layout.start_to_hole();
352        assert!(start_to_hole.is_empty());
353    }
354
355    database.remove_region(region3_i.into())?;
356
357    {
358        let regions = database.regions();
359        let index_to_region = regions.index_to_region();
360        assert!(index_to_region.len() == 3);
361        let region1 = database.get_region(region1_i.into())?;
362        assert!(region1.start() == 0);
363        assert!(region1.len() == 8000);
364        assert!(region1.reserved() == 2 * PAGE_SIZE);
365        let region2 = database.get_region(region2_i.into())?;
366        assert!(region2.start() == PAGE_SIZE * 3);
367        assert!(region2.len() == 0);
368        assert!(region2.reserved() == PAGE_SIZE);
369        assert!(database.get_region(region3_i.into()).is_err());
370        let id_to_index = regions.id_to_index();
371        assert!(id_to_index.len() == 2);
372        assert!(id_to_index.get("region1") == Some(&0));
373        assert!(id_to_index.get("region2") == Some(&1));
374        assert!(id_to_index.get("region3").is_none());
375
376        let layout = database.layout();
377        let start_to_index = layout.start_to_index();
378        assert!(start_to_index.len() == 2);
379        assert!(start_to_index.get(&0) == Some(&region1_i));
380        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
381        let start_to_hole = layout.start_to_hole();
382        assert!(start_to_hole.get(&(PAGE_SIZE * 2)) == Some(&PAGE_SIZE));
383    }
384
385    database.write_all_to_region(region1_i.into(), &[1; 8000])?;
386
387    {
388        let regions = database.regions();
389        let index_to_region = regions.index_to_region();
390        assert!(index_to_region.len() == 3);
391        let region1 = database.get_region(region1_i.into())?;
392        assert!(region1.start() == PAGE_SIZE * 4);
393        assert!(region1.len() == 16_000);
394        assert!(region1.reserved() == 4 * PAGE_SIZE);
395        let region2 = database.get_region(region2_i.into())?;
396        assert!(region2.start() == PAGE_SIZE * 3);
397        assert!(region2.len() == 0);
398        assert!(region2.reserved() == PAGE_SIZE);
399        assert!(database.get_region(region3_i.into()).is_err());
400        let id_to_index = regions.id_to_index();
401        assert!(id_to_index.len() == 2);
402        assert!(id_to_index.get("region1") == Some(&0));
403        assert!(id_to_index.get("region2") == Some(&1));
404        assert!(id_to_index.get("region3").is_none());
405
406        let layout = database.layout();
407        let start_to_index = layout.start_to_index();
408        assert!(start_to_index.len() == 2);
409        assert!(start_to_index.get(&(PAGE_SIZE * 4)) == Some(&region1_i));
410        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
411        let start_to_hole = layout.start_to_hole();
412        assert!(start_to_hole.get(&0) == Some(&(PAGE_SIZE * 3)));
413    }
414
415    database.write_all_to_region(region2_i.into(), &[1; 6000])?;
416
417    let (region4_i, _) = database.create_region_if_needed("region4")?;
418    database.remove_region(region2_i.into())?;
419    database.remove_region(region4_i.into())?;
420
421    let regions = database.regions();
422    dbg!(&regions);
423    let layout = database.layout();
424    dbg!(&layout);
425
426    Ok(())
427}
Source

pub fn layout(&self) -> RwLockReadGuard<'_, Layout>

Examples found in repository?
examples/db.rs (line 19)
5fn main() -> Result<()> {
6    let _ = fs::remove_dir_all("vecs");
7
8    let database = Database::open(Path::new("vecs"))?;
9
10    // let seqdb_min_len = PAGE_SIZE * 1_000_000;
11    // let min_regions = 20_000;
12
13    // seqdb.set_min_len(seqdb_min_len)?;
14    // seqdb.set_min_regions(min_regions)?;
15
16    let (region1_i, _) = database.create_region_if_needed("region1")?;
17
18    {
19        let layout = database.layout();
20        assert!(layout.start_to_index().len() == 1);
21        assert!(layout.start_to_index().first_key_value() == Some((&0, &0)));
22        assert!(layout.start_to_hole().is_empty());
23
24        let regions = database.regions();
25        assert!(
26            regions
27                .get_region_index_from_id("region1")
28                .is_some_and(|i| i == region1_i)
29        );
30
31        let region = database.get_region(region1_i.into())?;
32        assert!(region.start() == 0);
33        assert!(region.len() == 0);
34        assert!(region.reserved() == PAGE_SIZE);
35    }
36
37    database.write_all_to_region(region1_i.into(), &[0, 1, 2, 3, 4])?;
38
39    {
40        let region = database.get_region(region1_i.into())?;
41        assert!(region.start() == 0);
42        assert!(region.len() == 5);
43        assert!(region.reserved() == PAGE_SIZE);
44
45        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
46    }
47
48    database.write_all_to_region(region1_i.into(), &[5, 6, 7, 8, 9])?;
49
50    {
51        let region = database.get_region(region1_i.into())?;
52        assert!(region.start() == 0);
53        assert!(region.len() == 10);
54        assert!(region.reserved() == PAGE_SIZE);
55
56        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
57    }
58
59    database.write_all_to_region_at(region1_i.into(), &[1, 2], 0)?;
60
61    {
62        let region = database.get_region(region1_i.into())?;
63        assert!(region.start() == 0);
64        assert!(region.len() == 10);
65        assert!(region.reserved() == PAGE_SIZE);
66
67        assert!(database.mmap()[0..10] == [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]);
68    }
69
70    database.write_all_to_region_at(region1_i.into(), &[10, 11, 12, 13, 14, 15, 16, 17, 18], 4)?;
71
72    {
73        let region = database.get_region(region1_i.into())?;
74        assert!(region.start() == 0);
75        assert!(region.len() == 13);
76        assert!(region.reserved() == PAGE_SIZE);
77
78        assert!(
79            database.mmap()[0..20]
80                == [
81                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0
82                ]
83        );
84    }
85
86    database.write_all_to_region_at(region1_i.into(), &[0, 0, 0, 0, 0, 1], 13)?;
87
88    {
89        let region = database.get_region(region1_i.into())?;
90        assert!(region.start() == 0);
91        assert!(region.len() == 19);
92        assert!(region.reserved() == PAGE_SIZE);
93
94        assert!(
95            database.mmap()[0..20]
96                == [
97                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 1, 0
98                ]
99        );
100    }
101
102    dbg!(1);
103
104    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
105
106    {
107        let region = database.get_region(region1_i.into())?;
108        assert!(region.start() == 0);
109        assert!(region.len() == 8000);
110        assert!(region.reserved() == PAGE_SIZE * 2);
111
112        assert!(database.mmap()[0..8000] == [1; 8000]);
113        assert!(database.mmap()[8000..8001] == [0]);
114    }
115
116    println!("Disk usage - pre sync: {}", database.disk_usage());
117    database.flush()?;
118    println!("Disk usage - post sync: {}", database.disk_usage());
119
120    database.truncate_region(region1_i.into(), 10)?;
121    database.punch_holes()?;
122
123    {
124        let region = database.get_region(region1_i.into())?;
125        assert!(region.start() == 0);
126        assert!(region.len() == 10);
127        assert!(region.reserved() == PAGE_SIZE * 2);
128        // We only punch a hole in whole pages (4096 bytes)
129        // Thus the last byte of the page where the is still data wasn't overwritten when truncating
130        // And the first byte of the punched page was set to 0
131        assert!(database.mmap()[4095..=4096] == [1, 0]);
132    }
133
134    database.flush()?;
135    println!("Disk usage - post trunc: {}", database.disk_usage());
136
137    database.remove_region(region1_i.into())?;
138
139    database.flush()?;
140
141    println!("Disk usage - post remove: {}", database.disk_usage());
142
143    {
144        let regions = database.regions();
145        let index_to_region = regions.index_to_region();
146        assert!(index_to_region.len() == 1);
147        assert!(index_to_region[0].is_none());
148        assert!(regions.id_to_index().is_empty());
149
150        let layout = database.layout();
151        assert!(layout.start_to_index().is_empty());
152        assert!(layout.start_to_hole().len() == 1);
153    }
154
155    let (region1_i, _) = database.create_region_if_needed("region1")?;
156    let (region2_i, _) = database.create_region_if_needed("region2")?;
157    let (region3_i, _) = database.create_region_if_needed("region3")?;
158
159    // dbg!(seqdb.layout());
160
161    {
162        let regions = database.regions();
163        let index_to_region = regions.index_to_region();
164        assert!(index_to_region.len() == 3);
165        let region1 = database.get_region(region1_i.into())?;
166        assert!(region1.start() == 0);
167        assert!(region1.len() == 0);
168        assert!(region1.reserved() == PAGE_SIZE);
169        let region2 = database.get_region(region2_i.into())?;
170        assert!(region2.start() == PAGE_SIZE);
171        assert!(region2.len() == 0);
172        assert!(region2.reserved() == PAGE_SIZE);
173        let region3 = database.get_region(region3_i.into())?;
174        assert!(region3.start() == PAGE_SIZE * 2);
175        assert!(region3.len() == 0);
176        assert!(region3.reserved() == PAGE_SIZE);
177        let id_to_index = regions.id_to_index();
178        assert!(id_to_index.len() == 3);
179        assert!(id_to_index.get("region1") == Some(&0));
180        assert!(id_to_index.get("region2") == Some(&1));
181        assert!(id_to_index.get("region3") == Some(&2));
182
183        let layout = database.layout();
184        let start_to_index = layout.start_to_index();
185        assert!(start_to_index.len() == 3);
186        assert!(start_to_index.get(&0) == Some(&0));
187        assert!(start_to_index.get(&PAGE_SIZE) == Some(&1));
188        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&2));
189        assert!(layout.start_to_hole().is_empty());
190    }
191
192    database.remove_region(region2_i.into())?;
193
194    {
195        let regions = database.regions();
196        let index_to_region = regions.index_to_region();
197        assert!(index_to_region.len() == 3);
198        let region1 = database.get_region(region1_i.into())?;
199        assert!(region1.start() == 0);
200        assert!(region1.len() == 0);
201        assert!(region1.reserved() == PAGE_SIZE);
202        assert!(database.get_region(region2_i.into()).is_err());
203        assert!(
204            index_to_region
205                .get(region2_i)
206                .is_some_and(|opt| opt.is_none())
207        );
208        let region3 = database.get_region(region3_i.into())?;
209        assert!(region3.start() == PAGE_SIZE * 2);
210        assert!(region3.len() == 0);
211        assert!(region3.reserved() == PAGE_SIZE);
212        let id_to_index = regions.id_to_index();
213        assert!(id_to_index.len() == 2);
214        assert!(id_to_index.get("region1") == Some(&0));
215        assert!(id_to_index.get("region2").is_none());
216        assert!(id_to_index.get("region3") == Some(&2));
217
218        let layout = database.layout();
219        let start_to_index = layout.start_to_index();
220        assert!(start_to_index.len() == 2);
221        assert!(start_to_index.get(&0) == Some(&region1_i));
222        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
223        let start_to_hole = layout.start_to_hole();
224        assert!(start_to_hole.len() == 1);
225        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
226
227        drop(regions);
228        drop(layout);
229        assert!(
230            database
231                .remove_region(region2_i.into())
232                .is_ok_and(|o| o.is_none())
233        );
234    }
235
236    let (region2_i, _) = database.create_region_if_needed("region2")?;
237
238    {
239        assert!(region2_i == 1)
240    }
241
242    database.remove_region(region2_i.into())?;
243
244    {
245        let regions = database.regions();
246        let index_to_region = regions.index_to_region();
247        assert!(index_to_region.len() == 3);
248        let region1 = database.get_region(region1_i.into())?;
249        assert!(region1.start() == 0);
250        assert!(region1.len() == 0);
251        assert!(region1.reserved() == PAGE_SIZE);
252        assert!(database.get_region(region2_i.into()).is_err());
253        assert!(
254            index_to_region
255                .get(region2_i)
256                .is_some_and(|opt| opt.is_none())
257        );
258        let region3 = database.get_region(region3_i.into())?;
259        assert!(region3.start() == PAGE_SIZE * 2);
260        assert!(region3.len() == 0);
261        assert!(region3.reserved() == PAGE_SIZE);
262        let id_to_index = regions.id_to_index();
263        assert!(id_to_index.len() == 2);
264        assert!(id_to_index.get("region1") == Some(&0));
265        assert!(id_to_index.get("region2").is_none());
266        assert!(id_to_index.get("region3") == Some(&2));
267
268        let layout = database.layout();
269        let start_to_index = layout.start_to_index();
270        assert!(start_to_index.len() == 2);
271        assert!(start_to_index.get(&0) == Some(&region1_i));
272        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
273        let start_to_hole = layout.start_to_hole();
274        assert!(start_to_hole.len() == 1);
275        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
276
277        drop(regions);
278        drop(layout);
279        assert!(
280            database
281                .remove_region(region2_i.into())
282                .is_ok_and(|o| o.is_none())
283        );
284    }
285
286    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
287
288    {
289        let regions = database.regions();
290        let index_to_region = regions.index_to_region();
291        assert!(index_to_region.len() == 3);
292        let region1 = database.get_region(region1_i.into())?;
293        assert!(region1.start() == 0);
294        assert!(region1.len() == 8000);
295        assert!(region1.reserved() == 2 * PAGE_SIZE);
296        assert!(database.get_region(region2_i.into()).is_err());
297        assert!(
298            index_to_region
299                .get(region2_i)
300                .is_some_and(|opt| opt.is_none())
301        );
302        let region3 = database.get_region(region3_i.into())?;
303        assert!(region3.start() == PAGE_SIZE * 2);
304        assert!(region3.len() == 0);
305        assert!(region3.reserved() == PAGE_SIZE);
306        let id_to_index = regions.id_to_index();
307        assert!(id_to_index.len() == 2);
308        assert!(id_to_index.get("region1") == Some(&0));
309        assert!(id_to_index.get("region2").is_none());
310        assert!(id_to_index.get("region3") == Some(&2));
311
312        let layout = database.layout();
313        let start_to_index = layout.start_to_index();
314        assert!(start_to_index.len() == 2);
315        assert!(start_to_index.get(&0) == Some(&region1_i));
316        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
317        let start_to_hole = layout.start_to_hole();
318        assert!(start_to_hole.is_empty());
319    }
320
321    let (region2_i, _) = database.create_region_if_needed("region2")?;
322
323    {
324        let regions = database.regions();
325        let index_to_region = regions.index_to_region();
326        assert!(index_to_region.len() == 3);
327        let region1 = database.get_region(region1_i.into())?;
328        assert!(region1.start() == 0);
329        assert!(region1.len() == 8000);
330        assert!(region1.reserved() == 2 * PAGE_SIZE);
331        let region2 = database.get_region(region2_i.into())?;
332        assert!(region2.start() == PAGE_SIZE * 3);
333        assert!(region2.len() == 0);
334        assert!(region2.reserved() == PAGE_SIZE);
335        let region3 = database.get_region(region3_i.into())?;
336        assert!(region3.start() == PAGE_SIZE * 2);
337        assert!(region3.len() == 0);
338        assert!(region3.reserved() == PAGE_SIZE);
339        let id_to_index = regions.id_to_index();
340        assert!(id_to_index.len() == 3);
341        assert!(id_to_index.get("region1") == Some(&0));
342        assert!(id_to_index.get("region2") == Some(&1));
343        assert!(id_to_index.get("region3") == Some(&2));
344
345        let layout = database.layout();
346        let start_to_index = layout.start_to_index();
347        assert!(start_to_index.len() == 3);
348        assert!(start_to_index.get(&0) == Some(&region1_i));
349        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
350        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
351        let start_to_hole = layout.start_to_hole();
352        assert!(start_to_hole.is_empty());
353    }
354
355    database.remove_region(region3_i.into())?;
356
357    {
358        let regions = database.regions();
359        let index_to_region = regions.index_to_region();
360        assert!(index_to_region.len() == 3);
361        let region1 = database.get_region(region1_i.into())?;
362        assert!(region1.start() == 0);
363        assert!(region1.len() == 8000);
364        assert!(region1.reserved() == 2 * PAGE_SIZE);
365        let region2 = database.get_region(region2_i.into())?;
366        assert!(region2.start() == PAGE_SIZE * 3);
367        assert!(region2.len() == 0);
368        assert!(region2.reserved() == PAGE_SIZE);
369        assert!(database.get_region(region3_i.into()).is_err());
370        let id_to_index = regions.id_to_index();
371        assert!(id_to_index.len() == 2);
372        assert!(id_to_index.get("region1") == Some(&0));
373        assert!(id_to_index.get("region2") == Some(&1));
374        assert!(id_to_index.get("region3").is_none());
375
376        let layout = database.layout();
377        let start_to_index = layout.start_to_index();
378        assert!(start_to_index.len() == 2);
379        assert!(start_to_index.get(&0) == Some(&region1_i));
380        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
381        let start_to_hole = layout.start_to_hole();
382        assert!(start_to_hole.get(&(PAGE_SIZE * 2)) == Some(&PAGE_SIZE));
383    }
384
385    database.write_all_to_region(region1_i.into(), &[1; 8000])?;
386
387    {
388        let regions = database.regions();
389        let index_to_region = regions.index_to_region();
390        assert!(index_to_region.len() == 3);
391        let region1 = database.get_region(region1_i.into())?;
392        assert!(region1.start() == PAGE_SIZE * 4);
393        assert!(region1.len() == 16_000);
394        assert!(region1.reserved() == 4 * PAGE_SIZE);
395        let region2 = database.get_region(region2_i.into())?;
396        assert!(region2.start() == PAGE_SIZE * 3);
397        assert!(region2.len() == 0);
398        assert!(region2.reserved() == PAGE_SIZE);
399        assert!(database.get_region(region3_i.into()).is_err());
400        let id_to_index = regions.id_to_index();
401        assert!(id_to_index.len() == 2);
402        assert!(id_to_index.get("region1") == Some(&0));
403        assert!(id_to_index.get("region2") == Some(&1));
404        assert!(id_to_index.get("region3").is_none());
405
406        let layout = database.layout();
407        let start_to_index = layout.start_to_index();
408        assert!(start_to_index.len() == 2);
409        assert!(start_to_index.get(&(PAGE_SIZE * 4)) == Some(&region1_i));
410        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
411        let start_to_hole = layout.start_to_hole();
412        assert!(start_to_hole.get(&0) == Some(&(PAGE_SIZE * 3)));
413    }
414
415    database.write_all_to_region(region2_i.into(), &[1; 6000])?;
416
417    let (region4_i, _) = database.create_region_if_needed("region4")?;
418    database.remove_region(region2_i.into())?;
419    database.remove_region(region4_i.into())?;
420
421    let regions = database.regions();
422    dbg!(&regions);
423    let layout = database.layout();
424    dbg!(&layout);
425
426    Ok(())
427}
Source

pub fn mmap(&self) -> RwLockReadGuard<'_, MmapMut>

Examples found in repository?
examples/db.rs (line 45)
5fn main() -> Result<()> {
6    let _ = fs::remove_dir_all("vecs");
7
8    let database = Database::open(Path::new("vecs"))?;
9
10    // let seqdb_min_len = PAGE_SIZE * 1_000_000;
11    // let min_regions = 20_000;
12
13    // seqdb.set_min_len(seqdb_min_len)?;
14    // seqdb.set_min_regions(min_regions)?;
15
16    let (region1_i, _) = database.create_region_if_needed("region1")?;
17
18    {
19        let layout = database.layout();
20        assert!(layout.start_to_index().len() == 1);
21        assert!(layout.start_to_index().first_key_value() == Some((&0, &0)));
22        assert!(layout.start_to_hole().is_empty());
23
24        let regions = database.regions();
25        assert!(
26            regions
27                .get_region_index_from_id("region1")
28                .is_some_and(|i| i == region1_i)
29        );
30
31        let region = database.get_region(region1_i.into())?;
32        assert!(region.start() == 0);
33        assert!(region.len() == 0);
34        assert!(region.reserved() == PAGE_SIZE);
35    }
36
37    database.write_all_to_region(region1_i.into(), &[0, 1, 2, 3, 4])?;
38
39    {
40        let region = database.get_region(region1_i.into())?;
41        assert!(region.start() == 0);
42        assert!(region.len() == 5);
43        assert!(region.reserved() == PAGE_SIZE);
44
45        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
46    }
47
48    database.write_all_to_region(region1_i.into(), &[5, 6, 7, 8, 9])?;
49
50    {
51        let region = database.get_region(region1_i.into())?;
52        assert!(region.start() == 0);
53        assert!(region.len() == 10);
54        assert!(region.reserved() == PAGE_SIZE);
55
56        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
57    }
58
59    database.write_all_to_region_at(region1_i.into(), &[1, 2], 0)?;
60
61    {
62        let region = database.get_region(region1_i.into())?;
63        assert!(region.start() == 0);
64        assert!(region.len() == 10);
65        assert!(region.reserved() == PAGE_SIZE);
66
67        assert!(database.mmap()[0..10] == [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]);
68    }
69
70    database.write_all_to_region_at(region1_i.into(), &[10, 11, 12, 13, 14, 15, 16, 17, 18], 4)?;
71
72    {
73        let region = database.get_region(region1_i.into())?;
74        assert!(region.start() == 0);
75        assert!(region.len() == 13);
76        assert!(region.reserved() == PAGE_SIZE);
77
78        assert!(
79            database.mmap()[0..20]
80                == [
81                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0
82                ]
83        );
84    }
85
86    database.write_all_to_region_at(region1_i.into(), &[0, 0, 0, 0, 0, 1], 13)?;
87
88    {
89        let region = database.get_region(region1_i.into())?;
90        assert!(region.start() == 0);
91        assert!(region.len() == 19);
92        assert!(region.reserved() == PAGE_SIZE);
93
94        assert!(
95            database.mmap()[0..20]
96                == [
97                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 1, 0
98                ]
99        );
100    }
101
102    dbg!(1);
103
104    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
105
106    {
107        let region = database.get_region(region1_i.into())?;
108        assert!(region.start() == 0);
109        assert!(region.len() == 8000);
110        assert!(region.reserved() == PAGE_SIZE * 2);
111
112        assert!(database.mmap()[0..8000] == [1; 8000]);
113        assert!(database.mmap()[8000..8001] == [0]);
114    }
115
116    println!("Disk usage - pre sync: {}", database.disk_usage());
117    database.flush()?;
118    println!("Disk usage - post sync: {}", database.disk_usage());
119
120    database.truncate_region(region1_i.into(), 10)?;
121    database.punch_holes()?;
122
123    {
124        let region = database.get_region(region1_i.into())?;
125        assert!(region.start() == 0);
126        assert!(region.len() == 10);
127        assert!(region.reserved() == PAGE_SIZE * 2);
128        // We only punch a hole in whole pages (4096 bytes)
129        // Thus the last byte of the page where the is still data wasn't overwritten when truncating
130        // And the first byte of the punched page was set to 0
131        assert!(database.mmap()[4095..=4096] == [1, 0]);
132    }
133
134    database.flush()?;
135    println!("Disk usage - post trunc: {}", database.disk_usage());
136
137    database.remove_region(region1_i.into())?;
138
139    database.flush()?;
140
141    println!("Disk usage - post remove: {}", database.disk_usage());
142
143    {
144        let regions = database.regions();
145        let index_to_region = regions.index_to_region();
146        assert!(index_to_region.len() == 1);
147        assert!(index_to_region[0].is_none());
148        assert!(regions.id_to_index().is_empty());
149
150        let layout = database.layout();
151        assert!(layout.start_to_index().is_empty());
152        assert!(layout.start_to_hole().len() == 1);
153    }
154
155    let (region1_i, _) = database.create_region_if_needed("region1")?;
156    let (region2_i, _) = database.create_region_if_needed("region2")?;
157    let (region3_i, _) = database.create_region_if_needed("region3")?;
158
159    // dbg!(seqdb.layout());
160
161    {
162        let regions = database.regions();
163        let index_to_region = regions.index_to_region();
164        assert!(index_to_region.len() == 3);
165        let region1 = database.get_region(region1_i.into())?;
166        assert!(region1.start() == 0);
167        assert!(region1.len() == 0);
168        assert!(region1.reserved() == PAGE_SIZE);
169        let region2 = database.get_region(region2_i.into())?;
170        assert!(region2.start() == PAGE_SIZE);
171        assert!(region2.len() == 0);
172        assert!(region2.reserved() == PAGE_SIZE);
173        let region3 = database.get_region(region3_i.into())?;
174        assert!(region3.start() == PAGE_SIZE * 2);
175        assert!(region3.len() == 0);
176        assert!(region3.reserved() == PAGE_SIZE);
177        let id_to_index = regions.id_to_index();
178        assert!(id_to_index.len() == 3);
179        assert!(id_to_index.get("region1") == Some(&0));
180        assert!(id_to_index.get("region2") == Some(&1));
181        assert!(id_to_index.get("region3") == Some(&2));
182
183        let layout = database.layout();
184        let start_to_index = layout.start_to_index();
185        assert!(start_to_index.len() == 3);
186        assert!(start_to_index.get(&0) == Some(&0));
187        assert!(start_to_index.get(&PAGE_SIZE) == Some(&1));
188        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&2));
189        assert!(layout.start_to_hole().is_empty());
190    }
191
192    database.remove_region(region2_i.into())?;
193
194    {
195        let regions = database.regions();
196        let index_to_region = regions.index_to_region();
197        assert!(index_to_region.len() == 3);
198        let region1 = database.get_region(region1_i.into())?;
199        assert!(region1.start() == 0);
200        assert!(region1.len() == 0);
201        assert!(region1.reserved() == PAGE_SIZE);
202        assert!(database.get_region(region2_i.into()).is_err());
203        assert!(
204            index_to_region
205                .get(region2_i)
206                .is_some_and(|opt| opt.is_none())
207        );
208        let region3 = database.get_region(region3_i.into())?;
209        assert!(region3.start() == PAGE_SIZE * 2);
210        assert!(region3.len() == 0);
211        assert!(region3.reserved() == PAGE_SIZE);
212        let id_to_index = regions.id_to_index();
213        assert!(id_to_index.len() == 2);
214        assert!(id_to_index.get("region1") == Some(&0));
215        assert!(id_to_index.get("region2").is_none());
216        assert!(id_to_index.get("region3") == Some(&2));
217
218        let layout = database.layout();
219        let start_to_index = layout.start_to_index();
220        assert!(start_to_index.len() == 2);
221        assert!(start_to_index.get(&0) == Some(&region1_i));
222        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
223        let start_to_hole = layout.start_to_hole();
224        assert!(start_to_hole.len() == 1);
225        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
226
227        drop(regions);
228        drop(layout);
229        assert!(
230            database
231                .remove_region(region2_i.into())
232                .is_ok_and(|o| o.is_none())
233        );
234    }
235
236    let (region2_i, _) = database.create_region_if_needed("region2")?;
237
238    {
239        assert!(region2_i == 1)
240    }
241
242    database.remove_region(region2_i.into())?;
243
244    {
245        let regions = database.regions();
246        let index_to_region = regions.index_to_region();
247        assert!(index_to_region.len() == 3);
248        let region1 = database.get_region(region1_i.into())?;
249        assert!(region1.start() == 0);
250        assert!(region1.len() == 0);
251        assert!(region1.reserved() == PAGE_SIZE);
252        assert!(database.get_region(region2_i.into()).is_err());
253        assert!(
254            index_to_region
255                .get(region2_i)
256                .is_some_and(|opt| opt.is_none())
257        );
258        let region3 = database.get_region(region3_i.into())?;
259        assert!(region3.start() == PAGE_SIZE * 2);
260        assert!(region3.len() == 0);
261        assert!(region3.reserved() == PAGE_SIZE);
262        let id_to_index = regions.id_to_index();
263        assert!(id_to_index.len() == 2);
264        assert!(id_to_index.get("region1") == Some(&0));
265        assert!(id_to_index.get("region2").is_none());
266        assert!(id_to_index.get("region3") == Some(&2));
267
268        let layout = database.layout();
269        let start_to_index = layout.start_to_index();
270        assert!(start_to_index.len() == 2);
271        assert!(start_to_index.get(&0) == Some(&region1_i));
272        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
273        let start_to_hole = layout.start_to_hole();
274        assert!(start_to_hole.len() == 1);
275        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
276
277        drop(regions);
278        drop(layout);
279        assert!(
280            database
281                .remove_region(region2_i.into())
282                .is_ok_and(|o| o.is_none())
283        );
284    }
285
286    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
287
288    {
289        let regions = database.regions();
290        let index_to_region = regions.index_to_region();
291        assert!(index_to_region.len() == 3);
292        let region1 = database.get_region(region1_i.into())?;
293        assert!(region1.start() == 0);
294        assert!(region1.len() == 8000);
295        assert!(region1.reserved() == 2 * PAGE_SIZE);
296        assert!(database.get_region(region2_i.into()).is_err());
297        assert!(
298            index_to_region
299                .get(region2_i)
300                .is_some_and(|opt| opt.is_none())
301        );
302        let region3 = database.get_region(region3_i.into())?;
303        assert!(region3.start() == PAGE_SIZE * 2);
304        assert!(region3.len() == 0);
305        assert!(region3.reserved() == PAGE_SIZE);
306        let id_to_index = regions.id_to_index();
307        assert!(id_to_index.len() == 2);
308        assert!(id_to_index.get("region1") == Some(&0));
309        assert!(id_to_index.get("region2").is_none());
310        assert!(id_to_index.get("region3") == Some(&2));
311
312        let layout = database.layout();
313        let start_to_index = layout.start_to_index();
314        assert!(start_to_index.len() == 2);
315        assert!(start_to_index.get(&0) == Some(&region1_i));
316        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
317        let start_to_hole = layout.start_to_hole();
318        assert!(start_to_hole.is_empty());
319    }
320
321    let (region2_i, _) = database.create_region_if_needed("region2")?;
322
323    {
324        let regions = database.regions();
325        let index_to_region = regions.index_to_region();
326        assert!(index_to_region.len() == 3);
327        let region1 = database.get_region(region1_i.into())?;
328        assert!(region1.start() == 0);
329        assert!(region1.len() == 8000);
330        assert!(region1.reserved() == 2 * PAGE_SIZE);
331        let region2 = database.get_region(region2_i.into())?;
332        assert!(region2.start() == PAGE_SIZE * 3);
333        assert!(region2.len() == 0);
334        assert!(region2.reserved() == PAGE_SIZE);
335        let region3 = database.get_region(region3_i.into())?;
336        assert!(region3.start() == PAGE_SIZE * 2);
337        assert!(region3.len() == 0);
338        assert!(region3.reserved() == PAGE_SIZE);
339        let id_to_index = regions.id_to_index();
340        assert!(id_to_index.len() == 3);
341        assert!(id_to_index.get("region1") == Some(&0));
342        assert!(id_to_index.get("region2") == Some(&1));
343        assert!(id_to_index.get("region3") == Some(&2));
344
345        let layout = database.layout();
346        let start_to_index = layout.start_to_index();
347        assert!(start_to_index.len() == 3);
348        assert!(start_to_index.get(&0) == Some(&region1_i));
349        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
350        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
351        let start_to_hole = layout.start_to_hole();
352        assert!(start_to_hole.is_empty());
353    }
354
355    database.remove_region(region3_i.into())?;
356
357    {
358        let regions = database.regions();
359        let index_to_region = regions.index_to_region();
360        assert!(index_to_region.len() == 3);
361        let region1 = database.get_region(region1_i.into())?;
362        assert!(region1.start() == 0);
363        assert!(region1.len() == 8000);
364        assert!(region1.reserved() == 2 * PAGE_SIZE);
365        let region2 = database.get_region(region2_i.into())?;
366        assert!(region2.start() == PAGE_SIZE * 3);
367        assert!(region2.len() == 0);
368        assert!(region2.reserved() == PAGE_SIZE);
369        assert!(database.get_region(region3_i.into()).is_err());
370        let id_to_index = regions.id_to_index();
371        assert!(id_to_index.len() == 2);
372        assert!(id_to_index.get("region1") == Some(&0));
373        assert!(id_to_index.get("region2") == Some(&1));
374        assert!(id_to_index.get("region3").is_none());
375
376        let layout = database.layout();
377        let start_to_index = layout.start_to_index();
378        assert!(start_to_index.len() == 2);
379        assert!(start_to_index.get(&0) == Some(&region1_i));
380        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
381        let start_to_hole = layout.start_to_hole();
382        assert!(start_to_hole.get(&(PAGE_SIZE * 2)) == Some(&PAGE_SIZE));
383    }
384
385    database.write_all_to_region(region1_i.into(), &[1; 8000])?;
386
387    {
388        let regions = database.regions();
389        let index_to_region = regions.index_to_region();
390        assert!(index_to_region.len() == 3);
391        let region1 = database.get_region(region1_i.into())?;
392        assert!(region1.start() == PAGE_SIZE * 4);
393        assert!(region1.len() == 16_000);
394        assert!(region1.reserved() == 4 * PAGE_SIZE);
395        let region2 = database.get_region(region2_i.into())?;
396        assert!(region2.start() == PAGE_SIZE * 3);
397        assert!(region2.len() == 0);
398        assert!(region2.reserved() == PAGE_SIZE);
399        assert!(database.get_region(region3_i.into()).is_err());
400        let id_to_index = regions.id_to_index();
401        assert!(id_to_index.len() == 2);
402        assert!(id_to_index.get("region1") == Some(&0));
403        assert!(id_to_index.get("region2") == Some(&1));
404        assert!(id_to_index.get("region3").is_none());
405
406        let layout = database.layout();
407        let start_to_index = layout.start_to_index();
408        assert!(start_to_index.len() == 2);
409        assert!(start_to_index.get(&(PAGE_SIZE * 4)) == Some(&region1_i));
410        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
411        let start_to_hole = layout.start_to_hole();
412        assert!(start_to_hole.get(&0) == Some(&(PAGE_SIZE * 3)));
413    }
414
415    database.write_all_to_region(region2_i.into(), &[1; 6000])?;
416
417    let (region4_i, _) = database.create_region_if_needed("region4")?;
418    database.remove_region(region2_i.into())?;
419    database.remove_region(region4_i.into())?;
420
421    let regions = database.regions();
422    dbg!(&regions);
423    let layout = database.layout();
424    dbg!(&layout);
425
426    Ok(())
427}
Source

pub fn disk_usage(&self) -> String

Examples found in repository?
examples/db.rs (line 116)
5fn main() -> Result<()> {
6    let _ = fs::remove_dir_all("vecs");
7
8    let database = Database::open(Path::new("vecs"))?;
9
10    // let seqdb_min_len = PAGE_SIZE * 1_000_000;
11    // let min_regions = 20_000;
12
13    // seqdb.set_min_len(seqdb_min_len)?;
14    // seqdb.set_min_regions(min_regions)?;
15
16    let (region1_i, _) = database.create_region_if_needed("region1")?;
17
18    {
19        let layout = database.layout();
20        assert!(layout.start_to_index().len() == 1);
21        assert!(layout.start_to_index().first_key_value() == Some((&0, &0)));
22        assert!(layout.start_to_hole().is_empty());
23
24        let regions = database.regions();
25        assert!(
26            regions
27                .get_region_index_from_id("region1")
28                .is_some_and(|i| i == region1_i)
29        );
30
31        let region = database.get_region(region1_i.into())?;
32        assert!(region.start() == 0);
33        assert!(region.len() == 0);
34        assert!(region.reserved() == PAGE_SIZE);
35    }
36
37    database.write_all_to_region(region1_i.into(), &[0, 1, 2, 3, 4])?;
38
39    {
40        let region = database.get_region(region1_i.into())?;
41        assert!(region.start() == 0);
42        assert!(region.len() == 5);
43        assert!(region.reserved() == PAGE_SIZE);
44
45        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
46    }
47
48    database.write_all_to_region(region1_i.into(), &[5, 6, 7, 8, 9])?;
49
50    {
51        let region = database.get_region(region1_i.into())?;
52        assert!(region.start() == 0);
53        assert!(region.len() == 10);
54        assert!(region.reserved() == PAGE_SIZE);
55
56        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
57    }
58
59    database.write_all_to_region_at(region1_i.into(), &[1, 2], 0)?;
60
61    {
62        let region = database.get_region(region1_i.into())?;
63        assert!(region.start() == 0);
64        assert!(region.len() == 10);
65        assert!(region.reserved() == PAGE_SIZE);
66
67        assert!(database.mmap()[0..10] == [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]);
68    }
69
70    database.write_all_to_region_at(region1_i.into(), &[10, 11, 12, 13, 14, 15, 16, 17, 18], 4)?;
71
72    {
73        let region = database.get_region(region1_i.into())?;
74        assert!(region.start() == 0);
75        assert!(region.len() == 13);
76        assert!(region.reserved() == PAGE_SIZE);
77
78        assert!(
79            database.mmap()[0..20]
80                == [
81                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0
82                ]
83        );
84    }
85
86    database.write_all_to_region_at(region1_i.into(), &[0, 0, 0, 0, 0, 1], 13)?;
87
88    {
89        let region = database.get_region(region1_i.into())?;
90        assert!(region.start() == 0);
91        assert!(region.len() == 19);
92        assert!(region.reserved() == PAGE_SIZE);
93
94        assert!(
95            database.mmap()[0..20]
96                == [
97                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 1, 0
98                ]
99        );
100    }
101
102    dbg!(1);
103
104    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
105
106    {
107        let region = database.get_region(region1_i.into())?;
108        assert!(region.start() == 0);
109        assert!(region.len() == 8000);
110        assert!(region.reserved() == PAGE_SIZE * 2);
111
112        assert!(database.mmap()[0..8000] == [1; 8000]);
113        assert!(database.mmap()[8000..8001] == [0]);
114    }
115
116    println!("Disk usage - pre sync: {}", database.disk_usage());
117    database.flush()?;
118    println!("Disk usage - post sync: {}", database.disk_usage());
119
120    database.truncate_region(region1_i.into(), 10)?;
121    database.punch_holes()?;
122
123    {
124        let region = database.get_region(region1_i.into())?;
125        assert!(region.start() == 0);
126        assert!(region.len() == 10);
127        assert!(region.reserved() == PAGE_SIZE * 2);
128        // We only punch a hole in whole pages (4096 bytes)
129        // Thus the last byte of the page where the is still data wasn't overwritten when truncating
130        // And the first byte of the punched page was set to 0
131        assert!(database.mmap()[4095..=4096] == [1, 0]);
132    }
133
134    database.flush()?;
135    println!("Disk usage - post trunc: {}", database.disk_usage());
136
137    database.remove_region(region1_i.into())?;
138
139    database.flush()?;
140
141    println!("Disk usage - post remove: {}", database.disk_usage());
142
143    {
144        let regions = database.regions();
145        let index_to_region = regions.index_to_region();
146        assert!(index_to_region.len() == 1);
147        assert!(index_to_region[0].is_none());
148        assert!(regions.id_to_index().is_empty());
149
150        let layout = database.layout();
151        assert!(layout.start_to_index().is_empty());
152        assert!(layout.start_to_hole().len() == 1);
153    }
154
155    let (region1_i, _) = database.create_region_if_needed("region1")?;
156    let (region2_i, _) = database.create_region_if_needed("region2")?;
157    let (region3_i, _) = database.create_region_if_needed("region3")?;
158
159    // dbg!(seqdb.layout());
160
161    {
162        let regions = database.regions();
163        let index_to_region = regions.index_to_region();
164        assert!(index_to_region.len() == 3);
165        let region1 = database.get_region(region1_i.into())?;
166        assert!(region1.start() == 0);
167        assert!(region1.len() == 0);
168        assert!(region1.reserved() == PAGE_SIZE);
169        let region2 = database.get_region(region2_i.into())?;
170        assert!(region2.start() == PAGE_SIZE);
171        assert!(region2.len() == 0);
172        assert!(region2.reserved() == PAGE_SIZE);
173        let region3 = database.get_region(region3_i.into())?;
174        assert!(region3.start() == PAGE_SIZE * 2);
175        assert!(region3.len() == 0);
176        assert!(region3.reserved() == PAGE_SIZE);
177        let id_to_index = regions.id_to_index();
178        assert!(id_to_index.len() == 3);
179        assert!(id_to_index.get("region1") == Some(&0));
180        assert!(id_to_index.get("region2") == Some(&1));
181        assert!(id_to_index.get("region3") == Some(&2));
182
183        let layout = database.layout();
184        let start_to_index = layout.start_to_index();
185        assert!(start_to_index.len() == 3);
186        assert!(start_to_index.get(&0) == Some(&0));
187        assert!(start_to_index.get(&PAGE_SIZE) == Some(&1));
188        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&2));
189        assert!(layout.start_to_hole().is_empty());
190    }
191
192    database.remove_region(region2_i.into())?;
193
194    {
195        let regions = database.regions();
196        let index_to_region = regions.index_to_region();
197        assert!(index_to_region.len() == 3);
198        let region1 = database.get_region(region1_i.into())?;
199        assert!(region1.start() == 0);
200        assert!(region1.len() == 0);
201        assert!(region1.reserved() == PAGE_SIZE);
202        assert!(database.get_region(region2_i.into()).is_err());
203        assert!(
204            index_to_region
205                .get(region2_i)
206                .is_some_and(|opt| opt.is_none())
207        );
208        let region3 = database.get_region(region3_i.into())?;
209        assert!(region3.start() == PAGE_SIZE * 2);
210        assert!(region3.len() == 0);
211        assert!(region3.reserved() == PAGE_SIZE);
212        let id_to_index = regions.id_to_index();
213        assert!(id_to_index.len() == 2);
214        assert!(id_to_index.get("region1") == Some(&0));
215        assert!(id_to_index.get("region2").is_none());
216        assert!(id_to_index.get("region3") == Some(&2));
217
218        let layout = database.layout();
219        let start_to_index = layout.start_to_index();
220        assert!(start_to_index.len() == 2);
221        assert!(start_to_index.get(&0) == Some(&region1_i));
222        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
223        let start_to_hole = layout.start_to_hole();
224        assert!(start_to_hole.len() == 1);
225        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
226
227        drop(regions);
228        drop(layout);
229        assert!(
230            database
231                .remove_region(region2_i.into())
232                .is_ok_and(|o| o.is_none())
233        );
234    }
235
236    let (region2_i, _) = database.create_region_if_needed("region2")?;
237
238    {
239        assert!(region2_i == 1)
240    }
241
242    database.remove_region(region2_i.into())?;
243
244    {
245        let regions = database.regions();
246        let index_to_region = regions.index_to_region();
247        assert!(index_to_region.len() == 3);
248        let region1 = database.get_region(region1_i.into())?;
249        assert!(region1.start() == 0);
250        assert!(region1.len() == 0);
251        assert!(region1.reserved() == PAGE_SIZE);
252        assert!(database.get_region(region2_i.into()).is_err());
253        assert!(
254            index_to_region
255                .get(region2_i)
256                .is_some_and(|opt| opt.is_none())
257        );
258        let region3 = database.get_region(region3_i.into())?;
259        assert!(region3.start() == PAGE_SIZE * 2);
260        assert!(region3.len() == 0);
261        assert!(region3.reserved() == PAGE_SIZE);
262        let id_to_index = regions.id_to_index();
263        assert!(id_to_index.len() == 2);
264        assert!(id_to_index.get("region1") == Some(&0));
265        assert!(id_to_index.get("region2").is_none());
266        assert!(id_to_index.get("region3") == Some(&2));
267
268        let layout = database.layout();
269        let start_to_index = layout.start_to_index();
270        assert!(start_to_index.len() == 2);
271        assert!(start_to_index.get(&0) == Some(&region1_i));
272        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
273        let start_to_hole = layout.start_to_hole();
274        assert!(start_to_hole.len() == 1);
275        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
276
277        drop(regions);
278        drop(layout);
279        assert!(
280            database
281                .remove_region(region2_i.into())
282                .is_ok_and(|o| o.is_none())
283        );
284    }
285
286    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
287
288    {
289        let regions = database.regions();
290        let index_to_region = regions.index_to_region();
291        assert!(index_to_region.len() == 3);
292        let region1 = database.get_region(region1_i.into())?;
293        assert!(region1.start() == 0);
294        assert!(region1.len() == 8000);
295        assert!(region1.reserved() == 2 * PAGE_SIZE);
296        assert!(database.get_region(region2_i.into()).is_err());
297        assert!(
298            index_to_region
299                .get(region2_i)
300                .is_some_and(|opt| opt.is_none())
301        );
302        let region3 = database.get_region(region3_i.into())?;
303        assert!(region3.start() == PAGE_SIZE * 2);
304        assert!(region3.len() == 0);
305        assert!(region3.reserved() == PAGE_SIZE);
306        let id_to_index = regions.id_to_index();
307        assert!(id_to_index.len() == 2);
308        assert!(id_to_index.get("region1") == Some(&0));
309        assert!(id_to_index.get("region2").is_none());
310        assert!(id_to_index.get("region3") == Some(&2));
311
312        let layout = database.layout();
313        let start_to_index = layout.start_to_index();
314        assert!(start_to_index.len() == 2);
315        assert!(start_to_index.get(&0) == Some(&region1_i));
316        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
317        let start_to_hole = layout.start_to_hole();
318        assert!(start_to_hole.is_empty());
319    }
320
321    let (region2_i, _) = database.create_region_if_needed("region2")?;
322
323    {
324        let regions = database.regions();
325        let index_to_region = regions.index_to_region();
326        assert!(index_to_region.len() == 3);
327        let region1 = database.get_region(region1_i.into())?;
328        assert!(region1.start() == 0);
329        assert!(region1.len() == 8000);
330        assert!(region1.reserved() == 2 * PAGE_SIZE);
331        let region2 = database.get_region(region2_i.into())?;
332        assert!(region2.start() == PAGE_SIZE * 3);
333        assert!(region2.len() == 0);
334        assert!(region2.reserved() == PAGE_SIZE);
335        let region3 = database.get_region(region3_i.into())?;
336        assert!(region3.start() == PAGE_SIZE * 2);
337        assert!(region3.len() == 0);
338        assert!(region3.reserved() == PAGE_SIZE);
339        let id_to_index = regions.id_to_index();
340        assert!(id_to_index.len() == 3);
341        assert!(id_to_index.get("region1") == Some(&0));
342        assert!(id_to_index.get("region2") == Some(&1));
343        assert!(id_to_index.get("region3") == Some(&2));
344
345        let layout = database.layout();
346        let start_to_index = layout.start_to_index();
347        assert!(start_to_index.len() == 3);
348        assert!(start_to_index.get(&0) == Some(&region1_i));
349        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
350        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
351        let start_to_hole = layout.start_to_hole();
352        assert!(start_to_hole.is_empty());
353    }
354
355    database.remove_region(region3_i.into())?;
356
357    {
358        let regions = database.regions();
359        let index_to_region = regions.index_to_region();
360        assert!(index_to_region.len() == 3);
361        let region1 = database.get_region(region1_i.into())?;
362        assert!(region1.start() == 0);
363        assert!(region1.len() == 8000);
364        assert!(region1.reserved() == 2 * PAGE_SIZE);
365        let region2 = database.get_region(region2_i.into())?;
366        assert!(region2.start() == PAGE_SIZE * 3);
367        assert!(region2.len() == 0);
368        assert!(region2.reserved() == PAGE_SIZE);
369        assert!(database.get_region(region3_i.into()).is_err());
370        let id_to_index = regions.id_to_index();
371        assert!(id_to_index.len() == 2);
372        assert!(id_to_index.get("region1") == Some(&0));
373        assert!(id_to_index.get("region2") == Some(&1));
374        assert!(id_to_index.get("region3").is_none());
375
376        let layout = database.layout();
377        let start_to_index = layout.start_to_index();
378        assert!(start_to_index.len() == 2);
379        assert!(start_to_index.get(&0) == Some(&region1_i));
380        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
381        let start_to_hole = layout.start_to_hole();
382        assert!(start_to_hole.get(&(PAGE_SIZE * 2)) == Some(&PAGE_SIZE));
383    }
384
385    database.write_all_to_region(region1_i.into(), &[1; 8000])?;
386
387    {
388        let regions = database.regions();
389        let index_to_region = regions.index_to_region();
390        assert!(index_to_region.len() == 3);
391        let region1 = database.get_region(region1_i.into())?;
392        assert!(region1.start() == PAGE_SIZE * 4);
393        assert!(region1.len() == 16_000);
394        assert!(region1.reserved() == 4 * PAGE_SIZE);
395        let region2 = database.get_region(region2_i.into())?;
396        assert!(region2.start() == PAGE_SIZE * 3);
397        assert!(region2.len() == 0);
398        assert!(region2.reserved() == PAGE_SIZE);
399        assert!(database.get_region(region3_i.into()).is_err());
400        let id_to_index = regions.id_to_index();
401        assert!(id_to_index.len() == 2);
402        assert!(id_to_index.get("region1") == Some(&0));
403        assert!(id_to_index.get("region2") == Some(&1));
404        assert!(id_to_index.get("region3").is_none());
405
406        let layout = database.layout();
407        let start_to_index = layout.start_to_index();
408        assert!(start_to_index.len() == 2);
409        assert!(start_to_index.get(&(PAGE_SIZE * 4)) == Some(&region1_i));
410        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
411        let start_to_hole = layout.start_to_hole();
412        assert!(start_to_hole.get(&0) == Some(&(PAGE_SIZE * 3)));
413    }
414
415    database.write_all_to_region(region2_i.into(), &[1; 6000])?;
416
417    let (region4_i, _) = database.create_region_if_needed("region4")?;
418    database.remove_region(region2_i.into())?;
419    database.remove_region(region4_i.into())?;
420
421    let regions = database.regions();
422    dbg!(&regions);
423    let layout = database.layout();
424    dbg!(&layout);
425
426    Ok(())
427}
Source

pub fn flush(&self) -> Result<()>

Examples found in repository?
examples/db.rs (line 117)
5fn main() -> Result<()> {
6    let _ = fs::remove_dir_all("vecs");
7
8    let database = Database::open(Path::new("vecs"))?;
9
10    // let seqdb_min_len = PAGE_SIZE * 1_000_000;
11    // let min_regions = 20_000;
12
13    // seqdb.set_min_len(seqdb_min_len)?;
14    // seqdb.set_min_regions(min_regions)?;
15
16    let (region1_i, _) = database.create_region_if_needed("region1")?;
17
18    {
19        let layout = database.layout();
20        assert!(layout.start_to_index().len() == 1);
21        assert!(layout.start_to_index().first_key_value() == Some((&0, &0)));
22        assert!(layout.start_to_hole().is_empty());
23
24        let regions = database.regions();
25        assert!(
26            regions
27                .get_region_index_from_id("region1")
28                .is_some_and(|i| i == region1_i)
29        );
30
31        let region = database.get_region(region1_i.into())?;
32        assert!(region.start() == 0);
33        assert!(region.len() == 0);
34        assert!(region.reserved() == PAGE_SIZE);
35    }
36
37    database.write_all_to_region(region1_i.into(), &[0, 1, 2, 3, 4])?;
38
39    {
40        let region = database.get_region(region1_i.into())?;
41        assert!(region.start() == 0);
42        assert!(region.len() == 5);
43        assert!(region.reserved() == PAGE_SIZE);
44
45        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
46    }
47
48    database.write_all_to_region(region1_i.into(), &[5, 6, 7, 8, 9])?;
49
50    {
51        let region = database.get_region(region1_i.into())?;
52        assert!(region.start() == 0);
53        assert!(region.len() == 10);
54        assert!(region.reserved() == PAGE_SIZE);
55
56        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
57    }
58
59    database.write_all_to_region_at(region1_i.into(), &[1, 2], 0)?;
60
61    {
62        let region = database.get_region(region1_i.into())?;
63        assert!(region.start() == 0);
64        assert!(region.len() == 10);
65        assert!(region.reserved() == PAGE_SIZE);
66
67        assert!(database.mmap()[0..10] == [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]);
68    }
69
70    database.write_all_to_region_at(region1_i.into(), &[10, 11, 12, 13, 14, 15, 16, 17, 18], 4)?;
71
72    {
73        let region = database.get_region(region1_i.into())?;
74        assert!(region.start() == 0);
75        assert!(region.len() == 13);
76        assert!(region.reserved() == PAGE_SIZE);
77
78        assert!(
79            database.mmap()[0..20]
80                == [
81                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0
82                ]
83        );
84    }
85
86    database.write_all_to_region_at(region1_i.into(), &[0, 0, 0, 0, 0, 1], 13)?;
87
88    {
89        let region = database.get_region(region1_i.into())?;
90        assert!(region.start() == 0);
91        assert!(region.len() == 19);
92        assert!(region.reserved() == PAGE_SIZE);
93
94        assert!(
95            database.mmap()[0..20]
96                == [
97                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 1, 0
98                ]
99        );
100    }
101
102    dbg!(1);
103
104    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
105
106    {
107        let region = database.get_region(region1_i.into())?;
108        assert!(region.start() == 0);
109        assert!(region.len() == 8000);
110        assert!(region.reserved() == PAGE_SIZE * 2);
111
112        assert!(database.mmap()[0..8000] == [1; 8000]);
113        assert!(database.mmap()[8000..8001] == [0]);
114    }
115
116    println!("Disk usage - pre sync: {}", database.disk_usage());
117    database.flush()?;
118    println!("Disk usage - post sync: {}", database.disk_usage());
119
120    database.truncate_region(region1_i.into(), 10)?;
121    database.punch_holes()?;
122
123    {
124        let region = database.get_region(region1_i.into())?;
125        assert!(region.start() == 0);
126        assert!(region.len() == 10);
127        assert!(region.reserved() == PAGE_SIZE * 2);
128        // We only punch a hole in whole pages (4096 bytes)
129        // Thus the last byte of the page where the is still data wasn't overwritten when truncating
130        // And the first byte of the punched page was set to 0
131        assert!(database.mmap()[4095..=4096] == [1, 0]);
132    }
133
134    database.flush()?;
135    println!("Disk usage - post trunc: {}", database.disk_usage());
136
137    database.remove_region(region1_i.into())?;
138
139    database.flush()?;
140
141    println!("Disk usage - post remove: {}", database.disk_usage());
142
143    {
144        let regions = database.regions();
145        let index_to_region = regions.index_to_region();
146        assert!(index_to_region.len() == 1);
147        assert!(index_to_region[0].is_none());
148        assert!(regions.id_to_index().is_empty());
149
150        let layout = database.layout();
151        assert!(layout.start_to_index().is_empty());
152        assert!(layout.start_to_hole().len() == 1);
153    }
154
155    let (region1_i, _) = database.create_region_if_needed("region1")?;
156    let (region2_i, _) = database.create_region_if_needed("region2")?;
157    let (region3_i, _) = database.create_region_if_needed("region3")?;
158
159    // dbg!(seqdb.layout());
160
161    {
162        let regions = database.regions();
163        let index_to_region = regions.index_to_region();
164        assert!(index_to_region.len() == 3);
165        let region1 = database.get_region(region1_i.into())?;
166        assert!(region1.start() == 0);
167        assert!(region1.len() == 0);
168        assert!(region1.reserved() == PAGE_SIZE);
169        let region2 = database.get_region(region2_i.into())?;
170        assert!(region2.start() == PAGE_SIZE);
171        assert!(region2.len() == 0);
172        assert!(region2.reserved() == PAGE_SIZE);
173        let region3 = database.get_region(region3_i.into())?;
174        assert!(region3.start() == PAGE_SIZE * 2);
175        assert!(region3.len() == 0);
176        assert!(region3.reserved() == PAGE_SIZE);
177        let id_to_index = regions.id_to_index();
178        assert!(id_to_index.len() == 3);
179        assert!(id_to_index.get("region1") == Some(&0));
180        assert!(id_to_index.get("region2") == Some(&1));
181        assert!(id_to_index.get("region3") == Some(&2));
182
183        let layout = database.layout();
184        let start_to_index = layout.start_to_index();
185        assert!(start_to_index.len() == 3);
186        assert!(start_to_index.get(&0) == Some(&0));
187        assert!(start_to_index.get(&PAGE_SIZE) == Some(&1));
188        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&2));
189        assert!(layout.start_to_hole().is_empty());
190    }
191
192    database.remove_region(region2_i.into())?;
193
194    {
195        let regions = database.regions();
196        let index_to_region = regions.index_to_region();
197        assert!(index_to_region.len() == 3);
198        let region1 = database.get_region(region1_i.into())?;
199        assert!(region1.start() == 0);
200        assert!(region1.len() == 0);
201        assert!(region1.reserved() == PAGE_SIZE);
202        assert!(database.get_region(region2_i.into()).is_err());
203        assert!(
204            index_to_region
205                .get(region2_i)
206                .is_some_and(|opt| opt.is_none())
207        );
208        let region3 = database.get_region(region3_i.into())?;
209        assert!(region3.start() == PAGE_SIZE * 2);
210        assert!(region3.len() == 0);
211        assert!(region3.reserved() == PAGE_SIZE);
212        let id_to_index = regions.id_to_index();
213        assert!(id_to_index.len() == 2);
214        assert!(id_to_index.get("region1") == Some(&0));
215        assert!(id_to_index.get("region2").is_none());
216        assert!(id_to_index.get("region3") == Some(&2));
217
218        let layout = database.layout();
219        let start_to_index = layout.start_to_index();
220        assert!(start_to_index.len() == 2);
221        assert!(start_to_index.get(&0) == Some(&region1_i));
222        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
223        let start_to_hole = layout.start_to_hole();
224        assert!(start_to_hole.len() == 1);
225        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
226
227        drop(regions);
228        drop(layout);
229        assert!(
230            database
231                .remove_region(region2_i.into())
232                .is_ok_and(|o| o.is_none())
233        );
234    }
235
236    let (region2_i, _) = database.create_region_if_needed("region2")?;
237
238    {
239        assert!(region2_i == 1)
240    }
241
242    database.remove_region(region2_i.into())?;
243
244    {
245        let regions = database.regions();
246        let index_to_region = regions.index_to_region();
247        assert!(index_to_region.len() == 3);
248        let region1 = database.get_region(region1_i.into())?;
249        assert!(region1.start() == 0);
250        assert!(region1.len() == 0);
251        assert!(region1.reserved() == PAGE_SIZE);
252        assert!(database.get_region(region2_i.into()).is_err());
253        assert!(
254            index_to_region
255                .get(region2_i)
256                .is_some_and(|opt| opt.is_none())
257        );
258        let region3 = database.get_region(region3_i.into())?;
259        assert!(region3.start() == PAGE_SIZE * 2);
260        assert!(region3.len() == 0);
261        assert!(region3.reserved() == PAGE_SIZE);
262        let id_to_index = regions.id_to_index();
263        assert!(id_to_index.len() == 2);
264        assert!(id_to_index.get("region1") == Some(&0));
265        assert!(id_to_index.get("region2").is_none());
266        assert!(id_to_index.get("region3") == Some(&2));
267
268        let layout = database.layout();
269        let start_to_index = layout.start_to_index();
270        assert!(start_to_index.len() == 2);
271        assert!(start_to_index.get(&0) == Some(&region1_i));
272        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
273        let start_to_hole = layout.start_to_hole();
274        assert!(start_to_hole.len() == 1);
275        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
276
277        drop(regions);
278        drop(layout);
279        assert!(
280            database
281                .remove_region(region2_i.into())
282                .is_ok_and(|o| o.is_none())
283        );
284    }
285
286    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
287
288    {
289        let regions = database.regions();
290        let index_to_region = regions.index_to_region();
291        assert!(index_to_region.len() == 3);
292        let region1 = database.get_region(region1_i.into())?;
293        assert!(region1.start() == 0);
294        assert!(region1.len() == 8000);
295        assert!(region1.reserved() == 2 * PAGE_SIZE);
296        assert!(database.get_region(region2_i.into()).is_err());
297        assert!(
298            index_to_region
299                .get(region2_i)
300                .is_some_and(|opt| opt.is_none())
301        );
302        let region3 = database.get_region(region3_i.into())?;
303        assert!(region3.start() == PAGE_SIZE * 2);
304        assert!(region3.len() == 0);
305        assert!(region3.reserved() == PAGE_SIZE);
306        let id_to_index = regions.id_to_index();
307        assert!(id_to_index.len() == 2);
308        assert!(id_to_index.get("region1") == Some(&0));
309        assert!(id_to_index.get("region2").is_none());
310        assert!(id_to_index.get("region3") == Some(&2));
311
312        let layout = database.layout();
313        let start_to_index = layout.start_to_index();
314        assert!(start_to_index.len() == 2);
315        assert!(start_to_index.get(&0) == Some(&region1_i));
316        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
317        let start_to_hole = layout.start_to_hole();
318        assert!(start_to_hole.is_empty());
319    }
320
321    let (region2_i, _) = database.create_region_if_needed("region2")?;
322
323    {
324        let regions = database.regions();
325        let index_to_region = regions.index_to_region();
326        assert!(index_to_region.len() == 3);
327        let region1 = database.get_region(region1_i.into())?;
328        assert!(region1.start() == 0);
329        assert!(region1.len() == 8000);
330        assert!(region1.reserved() == 2 * PAGE_SIZE);
331        let region2 = database.get_region(region2_i.into())?;
332        assert!(region2.start() == PAGE_SIZE * 3);
333        assert!(region2.len() == 0);
334        assert!(region2.reserved() == PAGE_SIZE);
335        let region3 = database.get_region(region3_i.into())?;
336        assert!(region3.start() == PAGE_SIZE * 2);
337        assert!(region3.len() == 0);
338        assert!(region3.reserved() == PAGE_SIZE);
339        let id_to_index = regions.id_to_index();
340        assert!(id_to_index.len() == 3);
341        assert!(id_to_index.get("region1") == Some(&0));
342        assert!(id_to_index.get("region2") == Some(&1));
343        assert!(id_to_index.get("region3") == Some(&2));
344
345        let layout = database.layout();
346        let start_to_index = layout.start_to_index();
347        assert!(start_to_index.len() == 3);
348        assert!(start_to_index.get(&0) == Some(&region1_i));
349        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
350        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
351        let start_to_hole = layout.start_to_hole();
352        assert!(start_to_hole.is_empty());
353    }
354
355    database.remove_region(region3_i.into())?;
356
357    {
358        let regions = database.regions();
359        let index_to_region = regions.index_to_region();
360        assert!(index_to_region.len() == 3);
361        let region1 = database.get_region(region1_i.into())?;
362        assert!(region1.start() == 0);
363        assert!(region1.len() == 8000);
364        assert!(region1.reserved() == 2 * PAGE_SIZE);
365        let region2 = database.get_region(region2_i.into())?;
366        assert!(region2.start() == PAGE_SIZE * 3);
367        assert!(region2.len() == 0);
368        assert!(region2.reserved() == PAGE_SIZE);
369        assert!(database.get_region(region3_i.into()).is_err());
370        let id_to_index = regions.id_to_index();
371        assert!(id_to_index.len() == 2);
372        assert!(id_to_index.get("region1") == Some(&0));
373        assert!(id_to_index.get("region2") == Some(&1));
374        assert!(id_to_index.get("region3").is_none());
375
376        let layout = database.layout();
377        let start_to_index = layout.start_to_index();
378        assert!(start_to_index.len() == 2);
379        assert!(start_to_index.get(&0) == Some(&region1_i));
380        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
381        let start_to_hole = layout.start_to_hole();
382        assert!(start_to_hole.get(&(PAGE_SIZE * 2)) == Some(&PAGE_SIZE));
383    }
384
385    database.write_all_to_region(region1_i.into(), &[1; 8000])?;
386
387    {
388        let regions = database.regions();
389        let index_to_region = regions.index_to_region();
390        assert!(index_to_region.len() == 3);
391        let region1 = database.get_region(region1_i.into())?;
392        assert!(region1.start() == PAGE_SIZE * 4);
393        assert!(region1.len() == 16_000);
394        assert!(region1.reserved() == 4 * PAGE_SIZE);
395        let region2 = database.get_region(region2_i.into())?;
396        assert!(region2.start() == PAGE_SIZE * 3);
397        assert!(region2.len() == 0);
398        assert!(region2.reserved() == PAGE_SIZE);
399        assert!(database.get_region(region3_i.into()).is_err());
400        let id_to_index = regions.id_to_index();
401        assert!(id_to_index.len() == 2);
402        assert!(id_to_index.get("region1") == Some(&0));
403        assert!(id_to_index.get("region2") == Some(&1));
404        assert!(id_to_index.get("region3").is_none());
405
406        let layout = database.layout();
407        let start_to_index = layout.start_to_index();
408        assert!(start_to_index.len() == 2);
409        assert!(start_to_index.get(&(PAGE_SIZE * 4)) == Some(&region1_i));
410        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
411        let start_to_hole = layout.start_to_hole();
412        assert!(start_to_hole.get(&0) == Some(&(PAGE_SIZE * 3)));
413    }
414
415    database.write_all_to_region(region2_i.into(), &[1; 6000])?;
416
417    let (region4_i, _) = database.create_region_if_needed("region4")?;
418    database.remove_region(region2_i.into())?;
419    database.remove_region(region4_i.into())?;
420
421    let regions = database.regions();
422    dbg!(&regions);
423    let layout = database.layout();
424    dbg!(&layout);
425
426    Ok(())
427}
Source

pub fn flush_then_punch(&self) -> Result<()>

Source

pub fn punch_holes(&self) -> Result<()>

Examples found in repository?
examples/db.rs (line 121)
5fn main() -> Result<()> {
6    let _ = fs::remove_dir_all("vecs");
7
8    let database = Database::open(Path::new("vecs"))?;
9
10    // let seqdb_min_len = PAGE_SIZE * 1_000_000;
11    // let min_regions = 20_000;
12
13    // seqdb.set_min_len(seqdb_min_len)?;
14    // seqdb.set_min_regions(min_regions)?;
15
16    let (region1_i, _) = database.create_region_if_needed("region1")?;
17
18    {
19        let layout = database.layout();
20        assert!(layout.start_to_index().len() == 1);
21        assert!(layout.start_to_index().first_key_value() == Some((&0, &0)));
22        assert!(layout.start_to_hole().is_empty());
23
24        let regions = database.regions();
25        assert!(
26            regions
27                .get_region_index_from_id("region1")
28                .is_some_and(|i| i == region1_i)
29        );
30
31        let region = database.get_region(region1_i.into())?;
32        assert!(region.start() == 0);
33        assert!(region.len() == 0);
34        assert!(region.reserved() == PAGE_SIZE);
35    }
36
37    database.write_all_to_region(region1_i.into(), &[0, 1, 2, 3, 4])?;
38
39    {
40        let region = database.get_region(region1_i.into())?;
41        assert!(region.start() == 0);
42        assert!(region.len() == 5);
43        assert!(region.reserved() == PAGE_SIZE);
44
45        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]);
46    }
47
48    database.write_all_to_region(region1_i.into(), &[5, 6, 7, 8, 9])?;
49
50    {
51        let region = database.get_region(region1_i.into())?;
52        assert!(region.start() == 0);
53        assert!(region.len() == 10);
54        assert!(region.reserved() == PAGE_SIZE);
55
56        assert!(database.mmap()[0..10] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
57    }
58
59    database.write_all_to_region_at(region1_i.into(), &[1, 2], 0)?;
60
61    {
62        let region = database.get_region(region1_i.into())?;
63        assert!(region.start() == 0);
64        assert!(region.len() == 10);
65        assert!(region.reserved() == PAGE_SIZE);
66
67        assert!(database.mmap()[0..10] == [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]);
68    }
69
70    database.write_all_to_region_at(region1_i.into(), &[10, 11, 12, 13, 14, 15, 16, 17, 18], 4)?;
71
72    {
73        let region = database.get_region(region1_i.into())?;
74        assert!(region.start() == 0);
75        assert!(region.len() == 13);
76        assert!(region.reserved() == PAGE_SIZE);
77
78        assert!(
79            database.mmap()[0..20]
80                == [
81                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0
82                ]
83        );
84    }
85
86    database.write_all_to_region_at(region1_i.into(), &[0, 0, 0, 0, 0, 1], 13)?;
87
88    {
89        let region = database.get_region(region1_i.into())?;
90        assert!(region.start() == 0);
91        assert!(region.len() == 19);
92        assert!(region.reserved() == PAGE_SIZE);
93
94        assert!(
95            database.mmap()[0..20]
96                == [
97                    1, 2, 2, 3, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0, 1, 0
98                ]
99        );
100    }
101
102    dbg!(1);
103
104    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
105
106    {
107        let region = database.get_region(region1_i.into())?;
108        assert!(region.start() == 0);
109        assert!(region.len() == 8000);
110        assert!(region.reserved() == PAGE_SIZE * 2);
111
112        assert!(database.mmap()[0..8000] == [1; 8000]);
113        assert!(database.mmap()[8000..8001] == [0]);
114    }
115
116    println!("Disk usage - pre sync: {}", database.disk_usage());
117    database.flush()?;
118    println!("Disk usage - post sync: {}", database.disk_usage());
119
120    database.truncate_region(region1_i.into(), 10)?;
121    database.punch_holes()?;
122
123    {
124        let region = database.get_region(region1_i.into())?;
125        assert!(region.start() == 0);
126        assert!(region.len() == 10);
127        assert!(region.reserved() == PAGE_SIZE * 2);
128        // We only punch a hole in whole pages (4096 bytes)
129        // Thus the last byte of the page where the is still data wasn't overwritten when truncating
130        // And the first byte of the punched page was set to 0
131        assert!(database.mmap()[4095..=4096] == [1, 0]);
132    }
133
134    database.flush()?;
135    println!("Disk usage - post trunc: {}", database.disk_usage());
136
137    database.remove_region(region1_i.into())?;
138
139    database.flush()?;
140
141    println!("Disk usage - post remove: {}", database.disk_usage());
142
143    {
144        let regions = database.regions();
145        let index_to_region = regions.index_to_region();
146        assert!(index_to_region.len() == 1);
147        assert!(index_to_region[0].is_none());
148        assert!(regions.id_to_index().is_empty());
149
150        let layout = database.layout();
151        assert!(layout.start_to_index().is_empty());
152        assert!(layout.start_to_hole().len() == 1);
153    }
154
155    let (region1_i, _) = database.create_region_if_needed("region1")?;
156    let (region2_i, _) = database.create_region_if_needed("region2")?;
157    let (region3_i, _) = database.create_region_if_needed("region3")?;
158
159    // dbg!(seqdb.layout());
160
161    {
162        let regions = database.regions();
163        let index_to_region = regions.index_to_region();
164        assert!(index_to_region.len() == 3);
165        let region1 = database.get_region(region1_i.into())?;
166        assert!(region1.start() == 0);
167        assert!(region1.len() == 0);
168        assert!(region1.reserved() == PAGE_SIZE);
169        let region2 = database.get_region(region2_i.into())?;
170        assert!(region2.start() == PAGE_SIZE);
171        assert!(region2.len() == 0);
172        assert!(region2.reserved() == PAGE_SIZE);
173        let region3 = database.get_region(region3_i.into())?;
174        assert!(region3.start() == PAGE_SIZE * 2);
175        assert!(region3.len() == 0);
176        assert!(region3.reserved() == PAGE_SIZE);
177        let id_to_index = regions.id_to_index();
178        assert!(id_to_index.len() == 3);
179        assert!(id_to_index.get("region1") == Some(&0));
180        assert!(id_to_index.get("region2") == Some(&1));
181        assert!(id_to_index.get("region3") == Some(&2));
182
183        let layout = database.layout();
184        let start_to_index = layout.start_to_index();
185        assert!(start_to_index.len() == 3);
186        assert!(start_to_index.get(&0) == Some(&0));
187        assert!(start_to_index.get(&PAGE_SIZE) == Some(&1));
188        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&2));
189        assert!(layout.start_to_hole().is_empty());
190    }
191
192    database.remove_region(region2_i.into())?;
193
194    {
195        let regions = database.regions();
196        let index_to_region = regions.index_to_region();
197        assert!(index_to_region.len() == 3);
198        let region1 = database.get_region(region1_i.into())?;
199        assert!(region1.start() == 0);
200        assert!(region1.len() == 0);
201        assert!(region1.reserved() == PAGE_SIZE);
202        assert!(database.get_region(region2_i.into()).is_err());
203        assert!(
204            index_to_region
205                .get(region2_i)
206                .is_some_and(|opt| opt.is_none())
207        );
208        let region3 = database.get_region(region3_i.into())?;
209        assert!(region3.start() == PAGE_SIZE * 2);
210        assert!(region3.len() == 0);
211        assert!(region3.reserved() == PAGE_SIZE);
212        let id_to_index = regions.id_to_index();
213        assert!(id_to_index.len() == 2);
214        assert!(id_to_index.get("region1") == Some(&0));
215        assert!(id_to_index.get("region2").is_none());
216        assert!(id_to_index.get("region3") == Some(&2));
217
218        let layout = database.layout();
219        let start_to_index = layout.start_to_index();
220        assert!(start_to_index.len() == 2);
221        assert!(start_to_index.get(&0) == Some(&region1_i));
222        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
223        let start_to_hole = layout.start_to_hole();
224        assert!(start_to_hole.len() == 1);
225        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
226
227        drop(regions);
228        drop(layout);
229        assert!(
230            database
231                .remove_region(region2_i.into())
232                .is_ok_and(|o| o.is_none())
233        );
234    }
235
236    let (region2_i, _) = database.create_region_if_needed("region2")?;
237
238    {
239        assert!(region2_i == 1)
240    }
241
242    database.remove_region(region2_i.into())?;
243
244    {
245        let regions = database.regions();
246        let index_to_region = regions.index_to_region();
247        assert!(index_to_region.len() == 3);
248        let region1 = database.get_region(region1_i.into())?;
249        assert!(region1.start() == 0);
250        assert!(region1.len() == 0);
251        assert!(region1.reserved() == PAGE_SIZE);
252        assert!(database.get_region(region2_i.into()).is_err());
253        assert!(
254            index_to_region
255                .get(region2_i)
256                .is_some_and(|opt| opt.is_none())
257        );
258        let region3 = database.get_region(region3_i.into())?;
259        assert!(region3.start() == PAGE_SIZE * 2);
260        assert!(region3.len() == 0);
261        assert!(region3.reserved() == PAGE_SIZE);
262        let id_to_index = regions.id_to_index();
263        assert!(id_to_index.len() == 2);
264        assert!(id_to_index.get("region1") == Some(&0));
265        assert!(id_to_index.get("region2").is_none());
266        assert!(id_to_index.get("region3") == Some(&2));
267
268        let layout = database.layout();
269        let start_to_index = layout.start_to_index();
270        assert!(start_to_index.len() == 2);
271        assert!(start_to_index.get(&0) == Some(&region1_i));
272        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
273        let start_to_hole = layout.start_to_hole();
274        assert!(start_to_hole.len() == 1);
275        assert!(start_to_hole.get(&PAGE_SIZE) == Some(&PAGE_SIZE));
276
277        drop(regions);
278        drop(layout);
279        assert!(
280            database
281                .remove_region(region2_i.into())
282                .is_ok_and(|o| o.is_none())
283        );
284    }
285
286    database.write_all_to_region_at(region1_i.into(), &[1; 8000], 0)?;
287
288    {
289        let regions = database.regions();
290        let index_to_region = regions.index_to_region();
291        assert!(index_to_region.len() == 3);
292        let region1 = database.get_region(region1_i.into())?;
293        assert!(region1.start() == 0);
294        assert!(region1.len() == 8000);
295        assert!(region1.reserved() == 2 * PAGE_SIZE);
296        assert!(database.get_region(region2_i.into()).is_err());
297        assert!(
298            index_to_region
299                .get(region2_i)
300                .is_some_and(|opt| opt.is_none())
301        );
302        let region3 = database.get_region(region3_i.into())?;
303        assert!(region3.start() == PAGE_SIZE * 2);
304        assert!(region3.len() == 0);
305        assert!(region3.reserved() == PAGE_SIZE);
306        let id_to_index = regions.id_to_index();
307        assert!(id_to_index.len() == 2);
308        assert!(id_to_index.get("region1") == Some(&0));
309        assert!(id_to_index.get("region2").is_none());
310        assert!(id_to_index.get("region3") == Some(&2));
311
312        let layout = database.layout();
313        let start_to_index = layout.start_to_index();
314        assert!(start_to_index.len() == 2);
315        assert!(start_to_index.get(&0) == Some(&region1_i));
316        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
317        let start_to_hole = layout.start_to_hole();
318        assert!(start_to_hole.is_empty());
319    }
320
321    let (region2_i, _) = database.create_region_if_needed("region2")?;
322
323    {
324        let regions = database.regions();
325        let index_to_region = regions.index_to_region();
326        assert!(index_to_region.len() == 3);
327        let region1 = database.get_region(region1_i.into())?;
328        assert!(region1.start() == 0);
329        assert!(region1.len() == 8000);
330        assert!(region1.reserved() == 2 * PAGE_SIZE);
331        let region2 = database.get_region(region2_i.into())?;
332        assert!(region2.start() == PAGE_SIZE * 3);
333        assert!(region2.len() == 0);
334        assert!(region2.reserved() == PAGE_SIZE);
335        let region3 = database.get_region(region3_i.into())?;
336        assert!(region3.start() == PAGE_SIZE * 2);
337        assert!(region3.len() == 0);
338        assert!(region3.reserved() == PAGE_SIZE);
339        let id_to_index = regions.id_to_index();
340        assert!(id_to_index.len() == 3);
341        assert!(id_to_index.get("region1") == Some(&0));
342        assert!(id_to_index.get("region2") == Some(&1));
343        assert!(id_to_index.get("region3") == Some(&2));
344
345        let layout = database.layout();
346        let start_to_index = layout.start_to_index();
347        assert!(start_to_index.len() == 3);
348        assert!(start_to_index.get(&0) == Some(&region1_i));
349        assert!(start_to_index.get(&(PAGE_SIZE * 2)) == Some(&region3_i));
350        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
351        let start_to_hole = layout.start_to_hole();
352        assert!(start_to_hole.is_empty());
353    }
354
355    database.remove_region(region3_i.into())?;
356
357    {
358        let regions = database.regions();
359        let index_to_region = regions.index_to_region();
360        assert!(index_to_region.len() == 3);
361        let region1 = database.get_region(region1_i.into())?;
362        assert!(region1.start() == 0);
363        assert!(region1.len() == 8000);
364        assert!(region1.reserved() == 2 * PAGE_SIZE);
365        let region2 = database.get_region(region2_i.into())?;
366        assert!(region2.start() == PAGE_SIZE * 3);
367        assert!(region2.len() == 0);
368        assert!(region2.reserved() == PAGE_SIZE);
369        assert!(database.get_region(region3_i.into()).is_err());
370        let id_to_index = regions.id_to_index();
371        assert!(id_to_index.len() == 2);
372        assert!(id_to_index.get("region1") == Some(&0));
373        assert!(id_to_index.get("region2") == Some(&1));
374        assert!(id_to_index.get("region3").is_none());
375
376        let layout = database.layout();
377        let start_to_index = layout.start_to_index();
378        assert!(start_to_index.len() == 2);
379        assert!(start_to_index.get(&0) == Some(&region1_i));
380        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
381        let start_to_hole = layout.start_to_hole();
382        assert!(start_to_hole.get(&(PAGE_SIZE * 2)) == Some(&PAGE_SIZE));
383    }
384
385    database.write_all_to_region(region1_i.into(), &[1; 8000])?;
386
387    {
388        let regions = database.regions();
389        let index_to_region = regions.index_to_region();
390        assert!(index_to_region.len() == 3);
391        let region1 = database.get_region(region1_i.into())?;
392        assert!(region1.start() == PAGE_SIZE * 4);
393        assert!(region1.len() == 16_000);
394        assert!(region1.reserved() == 4 * PAGE_SIZE);
395        let region2 = database.get_region(region2_i.into())?;
396        assert!(region2.start() == PAGE_SIZE * 3);
397        assert!(region2.len() == 0);
398        assert!(region2.reserved() == PAGE_SIZE);
399        assert!(database.get_region(region3_i.into()).is_err());
400        let id_to_index = regions.id_to_index();
401        assert!(id_to_index.len() == 2);
402        assert!(id_to_index.get("region1") == Some(&0));
403        assert!(id_to_index.get("region2") == Some(&1));
404        assert!(id_to_index.get("region3").is_none());
405
406        let layout = database.layout();
407        let start_to_index = layout.start_to_index();
408        assert!(start_to_index.len() == 2);
409        assert!(start_to_index.get(&(PAGE_SIZE * 4)) == Some(&region1_i));
410        assert!(start_to_index.get(&(PAGE_SIZE * 3)) == Some(&region2_i));
411        let start_to_hole = layout.start_to_hole();
412        assert!(start_to_hole.get(&0) == Some(&(PAGE_SIZE * 3)));
413    }
414
415    database.write_all_to_region(region2_i.into(), &[1; 6000])?;
416
417    let (region4_i, _) = database.create_region_if_needed("region4")?;
418    database.remove_region(region2_i.into())?;
419    database.remove_region(region4_i.into())?;
420
421    let regions = database.regions();
422    dbg!(&regions);
423    let layout = database.layout();
424    dbg!(&layout);
425
426    Ok(())
427}
Source

pub fn path(&self) -> &Path

Trait Implementations§

Source§

impl Debug for DatabaseInner

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.