73 |
73 |
74 /// UUID used when first loading this `DirstateMap`. Used to check if |
74 /// UUID used when first loading this `DirstateMap`. Used to check if |
75 /// the UUID has been changed by another process since first read. |
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. |
76 /// Can be `None` if using dirstate v1 or if it's a brand new dirstate. |
77 pub(super) old_uuid: Option<Vec<u8>>, |
77 pub(super) old_uuid: Option<Vec<u8>>, |
|
78 |
|
79 /// Identity of the dirstate file (for dirstate-v1) or the docket file |
|
80 /// (v2). Used to detect if the file has changed from another process. |
|
81 /// Since it's always written atomically, we can compare the inode to |
|
82 /// check the file identity. |
|
83 /// |
|
84 /// TODO On non-Unix systems, something like hashing is a possibility? |
|
85 pub(super) identity: Option<u64>, |
78 |
86 |
79 pub(super) dirstate_version: DirstateVersion, |
87 pub(super) dirstate_version: DirstateVersion, |
80 |
88 |
81 /// Controlled by config option `devel.dirstate.v2.data_update_mode` |
89 /// Controlled by config option `devel.dirstate.v2.data_update_mode` |
82 pub(super) write_mode: DirstateMapWriteMode, |
90 pub(super) write_mode: DirstateMapWriteMode, |
466 nodes_with_copy_source_count: 0, |
474 nodes_with_copy_source_count: 0, |
467 ignore_patterns_hash: [0; on_disk::IGNORE_PATTERNS_HASH_LEN], |
475 ignore_patterns_hash: [0; on_disk::IGNORE_PATTERNS_HASH_LEN], |
468 unreachable_bytes: 0, |
476 unreachable_bytes: 0, |
469 old_data_size: 0, |
477 old_data_size: 0, |
470 old_uuid: None, |
478 old_uuid: None, |
|
479 identity: None, |
471 dirstate_version: DirstateVersion::V1, |
480 dirstate_version: DirstateVersion::V1, |
472 write_mode: DirstateMapWriteMode::Auto, |
481 write_mode: DirstateMapWriteMode::Auto, |
473 } |
482 } |
474 } |
483 } |
475 |
484 |
477 pub fn new_v2( |
486 pub fn new_v2( |
478 on_disk: &'on_disk [u8], |
487 on_disk: &'on_disk [u8], |
479 data_size: usize, |
488 data_size: usize, |
480 metadata: &[u8], |
489 metadata: &[u8], |
481 uuid: Vec<u8>, |
490 uuid: Vec<u8>, |
|
491 identity: Option<u64>, |
482 ) -> Result<Self, DirstateError> { |
492 ) -> Result<Self, DirstateError> { |
483 if let Some(data) = on_disk.get(..data_size) { |
493 if let Some(data) = on_disk.get(..data_size) { |
484 Ok(on_disk::read(data, metadata, uuid)?) |
494 Ok(on_disk::read(data, metadata, uuid, identity)?) |
485 } else { |
495 } else { |
486 Err(DirstateV2ParseError::new("not enough bytes on disk").into()) |
496 Err(DirstateV2ParseError::new("not enough bytes on disk").into()) |
487 } |
497 } |
488 } |
498 } |
489 |
499 |
490 #[timed] |
500 #[timed] |
491 pub fn new_v1( |
501 pub fn new_v1( |
492 on_disk: &'on_disk [u8], |
502 on_disk: &'on_disk [u8], |
|
503 identity: Option<u64>, |
493 ) -> Result<(Self, Option<DirstateParents>), DirstateError> { |
504 ) -> Result<(Self, Option<DirstateParents>), DirstateError> { |
494 let mut map = Self::empty(on_disk); |
505 let mut map = Self::empty(on_disk); |
495 if map.on_disk.is_empty() { |
506 if map.on_disk.is_empty() { |
496 return Ok((map, None)); |
507 return Ok((map, None)); |
497 } |
508 } |
1851 let mut map = OwningDirstateMap::new_v2( |
1863 let mut map = OwningDirstateMap::new_v2( |
1852 packed, |
1864 packed, |
1853 packed_len, |
1865 packed_len, |
1854 metadata.as_bytes(), |
1866 metadata.as_bytes(), |
1855 vec![], |
1867 vec![], |
|
1868 None, |
1856 )?; |
1869 )?; |
1857 |
1870 |
1858 // Check that everything is accounted for |
1871 // Check that everything is accounted for |
1859 assert!(map.contains_key(p(b"some/nested/added"))?); |
1872 assert!(map.contains_key(p(b"some/nested/added"))?); |
1860 assert!(map.contains_key(p(b"some/nested/removed"))?); |
1873 assert!(map.contains_key(p(b"some/nested/removed"))?); |