##// END OF EJS Templates
rust-dirstate: remember the data file uuid dirstate was loaded with...
Raphaël Gomès -
r51138:6cce0afc stable
parent child Browse files
Show More
@@ -573,10 +573,14 b' if rustmod is not None:'
573 573 testing.wait_on_cfg(self._ui, b'dirstate.post-docket-read-file')
574 574 if not self.docket.uuid:
575 575 data = b''
576 self._map = rustmod.DirstateMap.new_empty()
576 577 else:
577 578 data = self._read_v2_data()
578 579 self._map = rustmod.DirstateMap.new_v2(
579 data, self.docket.data_size, self.docket.tree_metadata
580 data,
581 self.docket.data_size,
582 self.docket.tree_metadata,
583 self.docket.uuid,
580 584 )
581 585 parents = self.docket.parents
582 586 else:
@@ -66,9 +66,16 b" pub struct DirstateMap<'on_disk> {"
66 66 pub(super) unreachable_bytes: u32,
67 67
68 68 /// Size of the data used to first load this `DirstateMap`. Used in case
69 /// we need to write some new metadata, but no new data on disk.
69 /// we need to write some new metadata, but no new data on disk,
70 /// as well as to detect writes that have happened in another process
71 /// since first read.
70 72 pub(super) old_data_size: usize,
71 73
74 /// UUID used when first loading this `DirstateMap`. Used to check if
75 /// the UUID has been changed by another process since first read.
76 /// Can be `None` if using dirstate v1 or if it's a brand new dirstate.
77 pub(super) old_uuid: Option<Vec<u8>>,
78
72 79 pub(super) dirstate_version: DirstateVersion,
73 80
74 81 /// Controlled by config option `devel.dirstate.v2.data_update_mode`
@@ -460,6 +467,7 b" impl<'on_disk> DirstateMap<'on_disk> {"
460 467 ignore_patterns_hash: [0; on_disk::IGNORE_PATTERNS_HASH_LEN],
461 468 unreachable_bytes: 0,
462 469 old_data_size: 0,
470 old_uuid: None,
463 471 dirstate_version: DirstateVersion::V1,
464 472 write_mode: DirstateMapWriteMode::Auto,
465 473 }
@@ -470,9 +478,10 b" impl<'on_disk> DirstateMap<'on_disk> {"
470 478 on_disk: &'on_disk [u8],
471 479 data_size: usize,
472 480 metadata: &[u8],
481 uuid: Vec<u8>,
473 482 ) -> Result<Self, DirstateError> {
474 483 if let Some(data) = on_disk.get(..data_size) {
475 Ok(on_disk::read(data, metadata)?)
484 Ok(on_disk::read(data, metadata, uuid)?)
476 485 } else {
477 486 Err(DirstateV2ParseError::new("not enough bytes on disk").into())
478 487 }
@@ -1843,6 +1852,7 b' mod tests {'
1843 1852 packed,
1844 1853 packed_len,
1845 1854 metadata.as_bytes(),
1855 vec![],
1846 1856 )?;
1847 1857
1848 1858 // Check that everything is accounted for
@@ -290,6 +290,7 b' pub fn read_docket('
290 290 pub(super) fn read<'on_disk>(
291 291 on_disk: &'on_disk [u8],
292 292 metadata: &[u8],
293 uuid: Vec<u8>,
293 294 ) -> Result<DirstateMap<'on_disk>, DirstateV2ParseError> {
294 295 if on_disk.is_empty() {
295 296 let mut map = DirstateMap::empty(on_disk);
@@ -312,6 +313,7 b" pub(super) fn read<'on_disk>("
312 313 ignore_patterns_hash: meta.ignore_patterns_hash,
313 314 unreachable_bytes: meta.unreachable_bytes.get(),
314 315 old_data_size: on_disk.len(),
316 old_uuid: Some(uuid),
315 317 dirstate_version: DirstateVersion::V2,
316 318 write_mode: DirstateMapWriteMode::Auto,
317 319 };
@@ -57,6 +57,7 b' impl OwningDirstateMap {'
57 57 on_disk: OnDisk,
58 58 data_size: usize,
59 59 metadata: &[u8],
60 uuid: Vec<u8>,
60 61 ) -> Result<Self, DirstateError>
61 62 where
62 63 OnDisk: Deref<Target = [u8]> + Send + 'static,
@@ -66,7 +67,7 b' impl OwningDirstateMap {'
66 67 OwningDirstateMapTryBuilder {
67 68 on_disk,
68 69 map_builder: |bytes| {
69 DirstateMap::new_v2(&bytes, data_size, metadata)
70 DirstateMap::new_v2(&bytes, data_size, metadata, uuid)
70 71 },
71 72 }
72 73 .try_build()
@@ -86,4 +87,12 b' impl OwningDirstateMap {'
86 87 pub fn on_disk(&self) -> &[u8] {
87 88 self.borrow_on_disk()
88 89 }
90
91 pub fn old_uuid(&self) -> Option<&[u8]> {
92 self.get_map().old_uuid.as_deref()
89 93 }
94
95 pub fn old_data_size(&self) -> usize {
96 self.get_map().old_data_size
97 }
98 }
@@ -383,6 +383,7 b' impl Repo {'
383 383 self.dirstate_parents.set(docket.parents());
384 384 self.dirstate_data_file_uuid
385 385 .set(Some(docket.uuid.to_owned()));
386 let uuid = docket.uuid.to_owned();
386 387 let data_size = docket.data_size();
387 388
388 389 let context = "between reading dirstate docket and data file";
@@ -415,16 +416,16 b' impl Repo {'
415 416 }
416 417 Err(e) => return Err(e.into()),
417 418 };
418 OwningDirstateMap::new_v2(contents, data_size, metadata)
419 OwningDirstateMap::new_v2(contents, data_size, metadata, uuid)
419 420 } else {
420 421 match self
421 422 .hg_vfs()
422 423 .mmap_open(docket.data_filename())
423 424 .io_not_found_as_none()
424 425 {
425 Ok(Some(data_mmap)) => {
426 OwningDirstateMap::new_v2(data_mmap, data_size, metadata)
427 }
426 Ok(Some(data_mmap)) => OwningDirstateMap::new_v2(
427 data_mmap, data_size, metadata, uuid,
428 ),
428 429 Ok(None) => {
429 430 // Race where the data file was deleted right after we
430 431 // read the docket, try again
@@ -66,18 +66,28 b' py_class!(pub class DirstateMap |py| {'
66 66 on_disk: PyBytes,
67 67 data_size: usize,
68 68 tree_metadata: PyBytes,
69 uuid: PyBytes,
69 70 ) -> PyResult<PyObject> {
70 71 let dirstate_error = |e: DirstateError| {
71 72 PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e))
72 73 };
73 74 let on_disk = PyBytesDeref::new(py, on_disk);
75 let uuid = uuid.data(py);
74 76 let map = OwningDirstateMap::new_v2(
75 on_disk, data_size, tree_metadata.data(py),
77 on_disk, data_size, tree_metadata.data(py), uuid.to_owned(),
76 78 ).map_err(dirstate_error)?;
77 79 let map = Self::create_instance(py, map)?;
78 80 Ok(map.into_object())
79 81 }
80 82
83 /// Returns an empty DirstateMap. Only used for a new dirstate.
84 @staticmethod
85 def new_empty() -> PyResult<PyObject> {
86 let map = OwningDirstateMap::new_empty(vec![]);
87 let map = Self::create_instance(py, map)?;
88 Ok(map.into_object())
89 }
90
81 91 def clear(&self) -> PyResult<PyObject> {
82 92 self.inner(py).borrow_mut().clear();
83 93 Ok(py.None())
General Comments 0
You need to be logged in to leave comments. Login now