##// END OF EJS Templates
rust-dirstate-v2: save proper data size if no new data on append...
Raphaël Gomès -
r50037:dd2503a6 stable
parent child Browse files
Show More
@@ -49,6 +49,10 b" pub struct DirstateMap<'on_disk> {"
49
49
50 /// How many bytes of `on_disk` are not used anymore
50 /// How many bytes of `on_disk` are not used anymore
51 pub(super) unreachable_bytes: u32,
51 pub(super) unreachable_bytes: u32,
52
53 /// Size of the data used to first load this `DirstateMap`. Used in case
54 /// we need to write some new metadata, but no new data on disk.
55 pub(super) old_data_size: usize,
52 }
56 }
53
57
54 /// Using a plain `HgPathBuf` of the full path from the repository root as a
58 /// Using a plain `HgPathBuf` of the full path from the repository root as a
@@ -429,6 +433,7 b" impl<'on_disk> DirstateMap<'on_disk> {"
429 nodes_with_copy_source_count: 0,
433 nodes_with_copy_source_count: 0,
430 ignore_patterns_hash: [0; on_disk::IGNORE_PATTERNS_HASH_LEN],
434 ignore_patterns_hash: [0; on_disk::IGNORE_PATTERNS_HASH_LEN],
431 unreachable_bytes: 0,
435 unreachable_bytes: 0,
436 old_data_size: 0,
432 }
437 }
433 }
438 }
434
439
@@ -989,12 +994,13 b' impl OwningDirstateMap {'
989 /// Returns new data and metadata together with whether that data should be
994 /// Returns new data and metadata together with whether that data should be
990 /// appended to the existing data file whose content is at
995 /// appended to the existing data file whose content is at
991 /// `map.on_disk` (true), instead of written to a new data file
996 /// `map.on_disk` (true), instead of written to a new data file
992 /// (false).
997 /// (false), and the previous size of data on disk.
993 #[timed]
998 #[timed]
994 pub fn pack_v2(
999 pub fn pack_v2(
995 &self,
1000 &self,
996 can_append: bool,
1001 can_append: bool,
997 ) -> Result<(Vec<u8>, on_disk::TreeMetadata, bool), DirstateError> {
1002 ) -> Result<(Vec<u8>, on_disk::TreeMetadata, bool, usize), DirstateError>
1003 {
998 let map = self.get_map();
1004 let map = self.get_map();
999 on_disk::write(map, can_append)
1005 on_disk::write(map, can_append)
1000 }
1006 }
@@ -290,6 +290,7 b" pub(super) fn read<'on_disk>("
290 nodes_with_copy_source_count: meta.nodes_with_copy_source_count.get(),
290 nodes_with_copy_source_count: meta.nodes_with_copy_source_count.get(),
291 ignore_patterns_hash: meta.ignore_patterns_hash,
291 ignore_patterns_hash: meta.ignore_patterns_hash,
292 unreachable_bytes: meta.unreachable_bytes.get(),
292 unreachable_bytes: meta.unreachable_bytes.get(),
293 old_data_size: on_disk.len(),
293 };
294 };
294 Ok(dirstate_map)
295 Ok(dirstate_map)
295 }
296 }
@@ -601,11 +602,11 b" pub(crate) fn for_each_tracked_path<'on_"
601 /// Returns new data and metadata, together with whether that data should be
602 /// Returns new data and metadata, together with whether that data should be
602 /// appended to the existing data file whose content is at
603 /// appended to the existing data file whose content is at
603 /// `dirstate_map.on_disk` (true), instead of written to a new data file
604 /// `dirstate_map.on_disk` (true), instead of written to a new data file
604 /// (false).
605 /// (false), and the previous size of data on disk.
605 pub(super) fn write(
606 pub(super) fn write(
606 dirstate_map: &DirstateMap,
607 dirstate_map: &DirstateMap,
607 can_append: bool,
608 can_append: bool,
608 ) -> Result<(Vec<u8>, TreeMetadata, bool), DirstateError> {
609 ) -> Result<(Vec<u8>, TreeMetadata, bool, usize), DirstateError> {
609 let append = can_append && dirstate_map.write_should_append();
610 let append = can_append && dirstate_map.write_should_append();
610
611
611 // This ignores the space for paths, and for nodes without an entry.
612 // This ignores the space for paths, and for nodes without an entry.
@@ -631,7 +632,7 b' pub(super) fn write('
631 unused: [0; 4],
632 unused: [0; 4],
632 ignore_patterns_hash: dirstate_map.ignore_patterns_hash,
633 ignore_patterns_hash: dirstate_map.ignore_patterns_hash,
633 };
634 };
634 Ok((writer.out, meta, append))
635 Ok((writer.out, meta, append, dirstate_map.old_data_size))
635 }
636 }
636
637
637 struct Writer<'dmap, 'on_disk> {
638 struct Writer<'dmap, 'on_disk> {
@@ -438,7 +438,8 b' impl Repo {'
438 let uuid = self.dirstate_data_file_uuid.get_or_init(self)?;
438 let uuid = self.dirstate_data_file_uuid.get_or_init(self)?;
439 let mut uuid = uuid.as_ref();
439 let mut uuid = uuid.as_ref();
440 let can_append = uuid.is_some();
440 let can_append = uuid.is_some();
441 let (data, tree_metadata, append) = map.pack_v2(can_append)?;
441 let (data, tree_metadata, append, old_data_size) =
442 map.pack_v2(can_append)?;
442 if !append {
443 if !append {
443 uuid = None
444 uuid = None
444 }
445 }
@@ -464,10 +465,19 b' impl Repo {'
464 // returns `ErrorKind::AlreadyExists`? Collision chance of two
465 // returns `ErrorKind::AlreadyExists`? Collision chance of two
465 // random IDs is one in 2**32
466 // random IDs is one in 2**32
466 let mut file = options.open(&data_filename)?;
467 let mut file = options.open(&data_filename)?;
467 file.write_all(&data)?;
468 if data.is_empty() {
468 file.flush()?;
469 // If we're not appending anything, the data size is the
469 // TODO: use https://doc.rust-lang.org/std/io/trait.Seek.html#method.stream_position when we require Rust 1.51+
470 // same as in the previous docket. It is *not* the file
470 file.seek(SeekFrom::Current(0))
471 // length, since it could have garbage at the end.
472 // We don't have to worry about it when we do have data
473 // to append since we rewrite the root node in this case.
474 Ok(old_data_size as u64)
475 } else {
476 file.write_all(&data)?;
477 file.flush()?;
478 // TODO: use https://doc.rust-lang.org/std/io/trait.Seek.html#method.stream_position when we require Rust 1.51+
479 file.seek(SeekFrom::Current(0))
480 }
471 })()
481 })()
472 .when_writing_file(&data_filename)?;
482 .when_writing_file(&data_filename)?;
473 DirstateDocket::serialize(
483 DirstateDocket::serialize(
@@ -211,7 +211,7 b' py_class!(pub class DirstateMap |py| {'
211 let inner = self.inner(py).borrow();
211 let inner = self.inner(py).borrow();
212 let result = inner.pack_v2(can_append);
212 let result = inner.pack_v2(can_append);
213 match result {
213 match result {
214 Ok((packed, tree_metadata, append)) => {
214 Ok((packed, tree_metadata, append, _old_data_size)) => {
215 let packed = PyBytes::new(py, &packed);
215 let packed = PyBytes::new(py, &packed);
216 let tree_metadata = PyBytes::new(py, tree_metadata.as_bytes());
216 let tree_metadata = PyBytes::new(py, tree_metadata.as_bytes());
217 let tuple = (packed, tree_metadata, append);
217 let tuple = (packed, tree_metadata, append);
General Comments 0
You need to be logged in to leave comments. Login now