##// END OF EJS Templates
dirstate-v2: Extend node flags to 16 bits...
Simon Sapin -
r49045:0524c135 default
parent child Browse files
Show More
@@ -18,7 +18,7 b" parsers = policy.importmod('parsers')"
18 # Must match the constant of the same name in
18 # Must match the constant of the same name in
19 # `rust/hg-core/src/dirstate_tree/on_disk.rs`
19 # `rust/hg-core/src/dirstate_tree/on_disk.rs`
20 TREE_METADATA_SIZE = 44
20 TREE_METADATA_SIZE = 44
21 NODE_SIZE = 43
21 NODE_SIZE = 44
22
22
23
23
24 # Must match the `TreeMetadata` Rust struct in
24 # Must match the `TreeMetadata` Rust struct in
@@ -50,7 +50,7 b" TREE_METADATA = struct.Struct('>LLLLL4s2"
50 # * 4 bytes: expected size
50 # * 4 bytes: expected size
51 # * 4 bytes: mtime seconds
51 # * 4 bytes: mtime seconds
52 # * 4 bytes: mtime nanoseconds
52 # * 4 bytes: mtime nanoseconds
53 NODE = struct.Struct('>LHHLHLLLLBlll')
53 NODE = struct.Struct('>LHHLHLLLLHlll')
54
54
55
55
56 assert TREE_METADATA_SIZE == TREE_METADATA.size
56 assert TREE_METADATA_SIZE == TREE_METADATA.size
@@ -372,7 +372,7 b' Node components are:'
372 This counter is used to implement `has_tracked_dir`.
372 This counter is used to implement `has_tracked_dir`.
373
373
374 * Offset 30:
374 * Offset 30:
375 A single `flags` byte that packs some boolean values as bits.
375 A `flags` fields that packs some boolean values as bits of a 16-bit integer.
376 Starting from least-significant, bit masks are::
376 Starting from least-significant, bit masks are::
377
377
378 WDIR_TRACKED = 1 << 0
378 WDIR_TRACKED = 1 << 0
@@ -384,22 +384,29 b' Node components are:'
384 MODE_IS_SYMLINK = 1 << 6
384 MODE_IS_SYMLINK = 1 << 6
385
385
386 The meaning of each bit is described below.
386 The meaning of each bit is described below.
387 Other bits are unset.
388
387
389 * Offset 31:
388 Other bits are unset.
389 They may be assigned meaning if the future,
390 with the limitation that Mercurial versions that pre-date such meaning
391 will always reset those bits to unset when writing nodes.
392 (A new node is written for any mutation in its subtree,
393 leaving the bytes of the old node unreachable
394 until the data file is rewritten entirely.)
395
396 * Offset 32:
390 A `size` field described below, as a 32-bit integer.
397 A `size` field described below, as a 32-bit integer.
391 Unlike in dirstate-v1, negative values are not used.
398 Unlike in dirstate-v1, negative values are not used.
392
399
393 * Offset 35:
400 * Offset 36:
394 The seconds component of an `mtime` field described below,
401 The seconds component of an `mtime` field described below,
395 as a 32-bit integer.
402 as a 32-bit integer.
396 Unlike in dirstate-v1, negative values are not used.
403 Unlike in dirstate-v1, negative values are not used.
397
404
398 * Offset 39:
405 * Offset 40:
399 The nanoseconds component of an `mtime` field described below,
406 The nanoseconds component of an `mtime` field described below,
400 as a 32-bit integer.
407 as a 32-bit integer.
401
408
402 * (Offset 43: end of this node)
409 * (Offset 44: end of this node)
403
410
404 The meaning of the boolean values packed in `flags` is:
411 The meaning of the boolean values packed in `flags` is:
405
412
@@ -33,7 +33,7 b' pub(super) type IgnorePatternsHash = [u8'
33
33
34 /// Must match constants of the same names in `mercurial/dirstateutils/v2.py`
34 /// Must match constants of the same names in `mercurial/dirstateutils/v2.py`
35 const TREE_METADATA_SIZE: usize = 44;
35 const TREE_METADATA_SIZE: usize = 44;
36 const NODE_SIZE: usize = 43;
36 const NODE_SIZE: usize = 44;
37
37
38 /// Make sure that size-affecting changes are made knowingly
38 /// Make sure that size-affecting changes are made knowingly
39 #[allow(unused)]
39 #[allow(unused)]
@@ -94,15 +94,14 b' pub(super) struct Node {'
94 children: ChildNodes,
94 children: ChildNodes,
95 pub(super) descendants_with_entry_count: Size,
95 pub(super) descendants_with_entry_count: Size,
96 pub(super) tracked_descendants_count: Size,
96 pub(super) tracked_descendants_count: Size,
97 flags: Flags,
97 flags: U16Be,
98 size: U32Be,
98 size: U32Be,
99 mtime: PackedTruncatedTimestamp,
99 mtime: PackedTruncatedTimestamp,
100 }
100 }
101
101
102 bitflags! {
102 bitflags! {
103 #[derive(BytesCast)]
104 #[repr(C)]
103 #[repr(C)]
105 struct Flags: u8 {
104 struct Flags: u16 {
106 const WDIR_TRACKED = 1 << 0;
105 const WDIR_TRACKED = 1 << 0;
107 const P1_TRACKED = 1 << 1;
106 const P1_TRACKED = 1 << 1;
108 const P2_INFO = 1 << 2;
107 const P2_INFO = 1 << 2;
@@ -296,8 +295,12 b' impl Node {'
296 })
295 })
297 }
296 }
298
297
298 fn flags(&self) -> Flags {
299 Flags::from_bits_truncate(self.flags.get())
300 }
301
299 fn has_entry(&self) -> bool {
302 fn has_entry(&self) -> bool {
300 self.flags.intersects(
303 self.flags().intersects(
301 Flags::WDIR_TRACKED | Flags::P1_TRACKED | Flags::P2_INFO,
304 Flags::WDIR_TRACKED | Flags::P1_TRACKED | Flags::P2_INFO,
302 )
305 )
303 }
306 }
@@ -318,7 +321,7 b' impl Node {'
318 &self,
321 &self,
319 ) -> Result<Option<TruncatedTimestamp>, DirstateV2ParseError> {
322 ) -> Result<Option<TruncatedTimestamp>, DirstateV2ParseError> {
320 Ok(
323 Ok(
321 if self.flags.contains(Flags::HAS_MTIME) && !self.has_entry() {
324 if self.flags().contains(Flags::HAS_MTIME) && !self.has_entry() {
322 Some(self.mtime.try_into()?)
325 Some(self.mtime.try_into()?)
323 } else {
326 } else {
324 None
327 None
@@ -327,12 +330,12 b' impl Node {'
327 }
330 }
328
331
329 fn synthesize_unix_mode(&self) -> u32 {
332 fn synthesize_unix_mode(&self) -> u32 {
330 let file_type = if self.flags.contains(Flags::MODE_IS_SYMLINK) {
333 let file_type = if self.flags().contains(Flags::MODE_IS_SYMLINK) {
331 libc::S_IFLNK
334 libc::S_IFLNK
332 } else {
335 } else {
333 libc::S_IFREG
336 libc::S_IFREG
334 };
337 };
335 let permisions = if self.flags.contains(Flags::MODE_EXEC_PERM) {
338 let permisions = if self.flags().contains(Flags::MODE_EXEC_PERM) {
336 0o755
339 0o755
337 } else {
340 } else {
338 0o644
341 0o644
@@ -342,15 +345,15 b' impl Node {'
342
345
343 fn assume_entry(&self) -> DirstateEntry {
346 fn assume_entry(&self) -> DirstateEntry {
344 // TODO: convert through raw bits instead?
347 // TODO: convert through raw bits instead?
345 let wdir_tracked = self.flags.contains(Flags::WDIR_TRACKED);
348 let wdir_tracked = self.flags().contains(Flags::WDIR_TRACKED);
346 let p1_tracked = self.flags.contains(Flags::P1_TRACKED);
349 let p1_tracked = self.flags().contains(Flags::P1_TRACKED);
347 let p2_info = self.flags.contains(Flags::P2_INFO);
350 let p2_info = self.flags().contains(Flags::P2_INFO);
348 let mode_size = if self.flags.contains(Flags::HAS_MODE_AND_SIZE) {
351 let mode_size = if self.flags().contains(Flags::HAS_MODE_AND_SIZE) {
349 Some((self.synthesize_unix_mode(), self.size.into()))
352 Some((self.synthesize_unix_mode(), self.size.into()))
350 } else {
353 } else {
351 None
354 None
352 };
355 };
353 let mtime = if self.flags.contains(Flags::HAS_MTIME) {
356 let mtime = if self.flags().contains(Flags::HAS_MTIME) {
354 Some(self.mtime.truncated_seconds.into())
357 Some(self.mtime.truncated_seconds.into())
355 } else {
358 } else {
356 None
359 None
@@ -600,7 +603,7 b" impl Writer<'_, '_> {"
600 tracked_descendants_count: node
603 tracked_descendants_count: node
601 .tracked_descendants_count
604 .tracked_descendants_count
602 .into(),
605 .into(),
603 flags,
606 flags: flags.bits().into(),
604 size,
607 size,
605 mtime,
608 mtime,
606 }
609 }
General Comments 0
You need to be logged in to leave comments. Login now