Show More
@@ -40,6 +40,8 b' static const int dirstate_flag_has_direc' | |||||
40 | static const int dirstate_flag_mode_exec_perm = 1 << 6; |
|
40 | static const int dirstate_flag_mode_exec_perm = 1 << 6; | |
41 | static const int dirstate_flag_mode_is_symlink = 1 << 7; |
|
41 | static const int dirstate_flag_mode_is_symlink = 1 << 7; | |
42 | static const int dirstate_flag_expected_state_is_modified = 1 << 8; |
|
42 | static const int dirstate_flag_expected_state_is_modified = 1 << 8; | |
|
43 | static const int dirstate_flag_all_unknown_recorded = 1 << 9; | |||
|
44 | static const int dirstate_flag_all_ignored_recorded = 1 << 10; | |||
43 |
|
45 | |||
44 | extern PyTypeObject dirstateItemType; |
|
46 | extern PyTypeObject dirstateItemType; | |
45 | #define dirstate_tuple_check(op) (Py_TYPE(op) == &dirstateItemType) |
|
47 | #define dirstate_tuple_check(op) (Py_TYPE(op) == &dirstateItemType) |
@@ -81,6 +81,9 b' def parse_nodes(map, copy_map, data, sta' | |||||
81 | """parse <len> nodes from <data> starting at offset <start> |
|
81 | """parse <len> nodes from <data> starting at offset <start> | |
82 |
|
82 | |||
83 | This is used by parse_dirstate to recursively fill `map` and `copy_map`. |
|
83 | This is used by parse_dirstate to recursively fill `map` and `copy_map`. | |
|
84 | ||||
|
85 | All directory specific information is ignored and do not need any | |||
|
86 | processing (HAS_DIRECTORY_MTIME, ALL_UNKNOWN_RECORDED, ALL_IGNORED_RECORDED) | |||
84 | """ |
|
87 | """ | |
85 | for i in range(len): |
|
88 | for i in range(len): | |
86 | node_start = start + NODE_SIZE * i |
|
89 | node_start = start + NODE_SIZE * i |
@@ -384,6 +384,8 b' Node components are:' | |||||
384 | MODE_EXEC_PERM = 1 << 6 |
|
384 | MODE_EXEC_PERM = 1 << 6 | |
385 | MODE_IS_SYMLINK = 1 << 7 |
|
385 | MODE_IS_SYMLINK = 1 << 7 | |
386 | EXPECTED_STATE_IS_MODIFIED = 1 << 8 |
|
386 | EXPECTED_STATE_IS_MODIFIED = 1 << 8 | |
|
387 | ALL_UNKNOWN_RECORDED = 1 << 9 | |||
|
388 | ALL_IGNORED_RECORDED = 1 << 10 | |||
387 |
|
389 | |||
388 | The meaning of each bit is described below. |
|
390 | The meaning of each bit is described below. | |
389 |
|
391 | |||
@@ -530,3 +532,29 b' by enabling it to skip `readdir` in more' | |||||
530 | does not need to do the same again. |
|
532 | does not need to do the same again. | |
531 | It is valid to never set this bit, |
|
533 | It is valid to never set this bit, | |
532 | and consider expected metadata ambiguous if it is set. |
|
534 | and consider expected metadata ambiguous if it is set. | |
|
535 | ||||
|
536 | `ALL_UNKNOWN_RECORDED` | |||
|
537 | If set, all "unknown" children existing on disk (at the time of the last | |||
|
538 | status) have been recorded and the `mtime` associated with | |||
|
539 | `HAS_DIRECTORY_MTIME` can be used for optimization even when "unknown" file | |||
|
540 | are listed. | |||
|
541 | ||||
|
542 | Note that the amount recorded "unknown" children can still be zero if None | |||
|
543 | where present. | |||
|
544 | ||||
|
545 | Also note that having this flag unset does not imply that no "unknown" | |||
|
546 | children have been recorded. Some might be present, but there is no garantee | |||
|
547 | that is will be all of them. | |||
|
548 | ||||
|
549 | `ALL_IGNORED_RECORDED` | |||
|
550 | If set, all "ignored" children existing on disk (at the time of the last | |||
|
551 | status) have been recorded and the `mtime` associated with | |||
|
552 | `HAS_DIRECTORY_MTIME` can be used for optimization even when "ignored" file | |||
|
553 | are listed. | |||
|
554 | ||||
|
555 | Note that the amount recorded "ignored" children can still be zero if None | |||
|
556 | where present. | |||
|
557 | ||||
|
558 | Also note that having this flag unset does not imply that no "ignored" | |||
|
559 | children have been recorded. Some might be present, but there is no garantee | |||
|
560 | that is will be all of them. |
@@ -54,6 +54,8 b' DIRSTATE_V2_HAS_FILE_MTIME = 1 << 4' | |||||
54 | DIRSTATE_V2_MODE_EXEC_PERM = 1 << 6 |
|
54 | DIRSTATE_V2_MODE_EXEC_PERM = 1 << 6 | |
55 | DIRSTATE_V2_MODE_IS_SYMLINK = 1 << 7 |
|
55 | DIRSTATE_V2_MODE_IS_SYMLINK = 1 << 7 | |
56 | DIRSTATE_V2_EXPECTED_STATE_IS_MODIFIED = 1 << 8 |
|
56 | DIRSTATE_V2_EXPECTED_STATE_IS_MODIFIED = 1 << 8 | |
|
57 | DIRSTATE_V2_ALL_UNKNOWN_RECORDED = 1 << 9 | |||
|
58 | DIRSTATE_V2_ALL_IGNORED_RECORDED = 1 << 10 | |||
57 |
|
59 | |||
58 |
|
60 | |||
59 | @attr.s(slots=True, init=False) |
|
61 | @attr.s(slots=True, init=False) | |
@@ -340,6 +342,9 b' class DirstateItem(object):' | |||||
340 | flags |= DIRSTATE_V2_MODE_IS_SYMLINK |
|
342 | flags |= DIRSTATE_V2_MODE_IS_SYMLINK | |
341 | if self._mtime is not None: |
|
343 | if self._mtime is not None: | |
342 | flags |= DIRSTATE_V2_HAS_FILE_MTIME |
|
344 | flags |= DIRSTATE_V2_HAS_FILE_MTIME | |
|
345 | # Note: we do not need to do anything regarding | |||
|
346 | # DIRSTATE_V2_ALL_UNKNOWN_RECORDED and DIRSTATE_V2_ALL_IGNORED_RECORDED | |||
|
347 | # since we never set _DIRSTATE_V2_HAS_DIRCTORY_MTIME | |||
343 | return (flags, self._size or 0, self._mtime or 0) |
|
348 | return (flags, self._size or 0, self._mtime or 0) | |
344 |
|
349 | |||
345 | def v1_state(self): |
|
350 | def v1_state(self): |
@@ -111,6 +111,8 b' bitflags! {' | |||||
111 | const MODE_EXEC_PERM = 1 << 6; |
|
111 | const MODE_EXEC_PERM = 1 << 6; | |
112 | const MODE_IS_SYMLINK = 1 << 7; |
|
112 | const MODE_IS_SYMLINK = 1 << 7; | |
113 | const EXPECTED_STATE_IS_MODIFIED = 1 << 8; |
|
113 | const EXPECTED_STATE_IS_MODIFIED = 1 << 8; | |
|
114 | const ALL_UNKNOWN_RECORDED = 1 << 9; | |||
|
115 | const ALL_IGNORED_RECORDED = 1 << 10; | |||
114 | } |
|
116 | } | |
115 | } |
|
117 | } | |
116 |
|
118 | |||
@@ -322,7 +324,11 b' impl Node {' | |||||
322 | pub(super) fn cached_directory_mtime( |
|
324 | pub(super) fn cached_directory_mtime( | |
323 | &self, |
|
325 | &self, | |
324 | ) -> Result<Option<TruncatedTimestamp>, DirstateV2ParseError> { |
|
326 | ) -> Result<Option<TruncatedTimestamp>, DirstateV2ParseError> { | |
325 | if self.flags().contains(Flags::HAS_DIRECTORY_MTIME) { |
|
327 | // For now we do not have code to handle ALL_UNKNOWN_RECORDED, so we | |
|
328 | // ignore the mtime if the flag is set. | |||
|
329 | if self.flags().contains(Flags::HAS_DIRECTORY_MTIME) | |||
|
330 | && self.flags().contains(Flags::ALL_UNKNOWN_RECORDED) | |||
|
331 | { | |||
326 | if self.flags().contains(Flags::HAS_FILE_MTIME) { |
|
332 | if self.flags().contains(Flags::HAS_FILE_MTIME) { | |
327 | Err(DirstateV2ParseError) |
|
333 | Err(DirstateV2ParseError) | |
328 | } else { |
|
334 | } else { | |
@@ -589,7 +595,18 b" impl Writer<'_, '_> {" | |||||
589 | Node::from_dirstate_entry(entry) |
|
595 | Node::from_dirstate_entry(entry) | |
590 | } |
|
596 | } | |
591 | dirstate_map::NodeData::CachedDirectory { mtime } => ( |
|
597 | dirstate_map::NodeData::CachedDirectory { mtime } => ( | |
592 | Flags::HAS_DIRECTORY_MTIME, |
|
598 | // we currently never set a mtime if unknown file | |
|
599 | // are present. | |||
|
600 | // So if we have a mtime for a directory, we know | |||
|
601 | // they are no unknown | |||
|
602 | // files and we | |||
|
603 | // blindly set ALL_UNKNOWN_RECORDED. | |||
|
604 | // | |||
|
605 | // We never set ALL_IGNORED_RECORDED since we | |||
|
606 | // don't track that case | |||
|
607 | // currently. | |||
|
608 | Flags::HAS_DIRECTORY_MTIME | |||
|
609 | | Flags::ALL_UNKNOWN_RECORDED, | |||
593 | 0.into(), |
|
610 | 0.into(), | |
594 | (*mtime).into(), |
|
611 | (*mtime).into(), | |
595 | ), |
|
612 | ), |
General Comments 0
You need to be logged in to leave comments.
Login now