Show More
@@ -49,6 +49,10 b" pub struct DirstateMap<'on_disk> {" | |||
|
49 | 49 | |
|
50 | 50 | /// How many bytes of `on_disk` are not used anymore |
|
51 | 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 | 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 | 433 | nodes_with_copy_source_count: 0, |
|
430 | 434 | ignore_patterns_hash: [0; on_disk::IGNORE_PATTERNS_HASH_LEN], |
|
431 | 435 | unreachable_bytes: 0, |
|
436 | old_data_size: 0, | |
|
432 | 437 | } |
|
433 | 438 | } |
|
434 | 439 | |
@@ -989,12 +994,13 b' impl OwningDirstateMap {' | |||
|
989 | 994 | /// Returns new data and metadata together with whether that data should be |
|
990 | 995 | /// appended to the existing data file whose content is at |
|
991 | 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 | 998 | #[timed] |
|
994 | 999 | pub fn pack_v2( |
|
995 | 1000 | &self, |
|
996 | 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 | 1004 | let map = self.get_map(); |
|
999 | 1005 | on_disk::write(map, can_append) |
|
1000 | 1006 | } |
@@ -290,6 +290,7 b" pub(super) fn read<'on_disk>(" | |||
|
290 | 290 | nodes_with_copy_source_count: meta.nodes_with_copy_source_count.get(), |
|
291 | 291 | ignore_patterns_hash: meta.ignore_patterns_hash, |
|
292 | 292 | unreachable_bytes: meta.unreachable_bytes.get(), |
|
293 | old_data_size: on_disk.len(), | |
|
293 | 294 | }; |
|
294 | 295 | Ok(dirstate_map) |
|
295 | 296 | } |
@@ -601,11 +602,11 b" pub(crate) fn for_each_tracked_path<'on_" | |||
|
601 | 602 | /// Returns new data and metadata, together with whether that data should be |
|
602 | 603 | /// appended to the existing data file whose content is at |
|
603 | 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 | 606 | pub(super) fn write( |
|
606 | 607 | dirstate_map: &DirstateMap, |
|
607 | 608 | can_append: bool, |
|
608 | ) -> Result<(Vec<u8>, TreeMetadata, bool), DirstateError> { | |
|
609 | ) -> Result<(Vec<u8>, TreeMetadata, bool, usize), DirstateError> { | |
|
609 | 610 | let append = can_append && dirstate_map.write_should_append(); |
|
610 | 611 | |
|
611 | 612 | // This ignores the space for paths, and for nodes without an entry. |
@@ -631,7 +632,7 b' pub(super) fn write(' | |||
|
631 | 632 | unused: [0; 4], |
|
632 | 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 | 638 | struct Writer<'dmap, 'on_disk> { |
@@ -438,7 +438,8 b' impl Repo {' | |||
|
438 | 438 | let uuid = self.dirstate_data_file_uuid.get_or_init(self)?; |
|
439 | 439 | let mut uuid = uuid.as_ref(); |
|
440 | 440 | let can_append = uuid.is_some(); |
|
441 |
let (data, tree_metadata, append) = |
|
|
441 | let (data, tree_metadata, append, old_data_size) = | |
|
442 | map.pack_v2(can_append)?; | |
|
442 | 443 | if !append { |
|
443 | 444 | uuid = None |
|
444 | 445 | } |
@@ -464,10 +465,19 b' impl Repo {' | |||
|
464 | 465 | // returns `ErrorKind::AlreadyExists`? Collision chance of two |
|
465 | 466 | // random IDs is one in 2**32 |
|
466 | 467 | let mut file = options.open(&data_filename)?; |
|
467 | file.write_all(&data)?; | |
|
468 | file.flush()?; | |
|
469 | // TODO: use https://doc.rust-lang.org/std/io/trait.Seek.html#method.stream_position when we require Rust 1.51+ | |
|
470 | file.seek(SeekFrom::Current(0)) | |
|
468 | if data.is_empty() { | |
|
469 | // If we're not appending anything, the data size is the | |
|
470 | // same as in the previous docket. It is *not* the file | |
|
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 | 482 | .when_writing_file(&data_filename)?; |
|
473 | 483 | DirstateDocket::serialize( |
@@ -211,7 +211,7 b' py_class!(pub class DirstateMap |py| {' | |||
|
211 | 211 | let inner = self.inner(py).borrow(); |
|
212 | 212 | let result = inner.pack_v2(can_append); |
|
213 | 213 | match result { |
|
214 | Ok((packed, tree_metadata, append)) => { | |
|
214 | Ok((packed, tree_metadata, append, _old_data_size)) => { | |
|
215 | 215 | let packed = PyBytes::new(py, &packed); |
|
216 | 216 | let tree_metadata = PyBytes::new(py, tree_metadata.as_bytes()); |
|
217 | 217 | let tuple = (packed, tree_metadata, append); |
General Comments 0
You need to be logged in to leave comments.
Login now