22 use crate::PatternFileWarning; |
22 use crate::PatternFileWarning; |
23 use crate::StateMapIter; |
23 use crate::StateMapIter; |
24 use crate::StatusError; |
24 use crate::StatusError; |
25 use crate::StatusOptions; |
25 use crate::StatusOptions; |
26 |
26 |
27 pub struct DirstateMap { |
27 pub struct DirstateMap<'on_disk> { |
|
28 /// Contents of the `.hg/dirstate` file |
|
29 on_disk: &'on_disk [u8], |
|
30 |
28 pub(super) root: ChildNodes, |
31 pub(super) root: ChildNodes, |
29 |
32 |
30 /// Number of nodes anywhere in the tree that have `.entry.is_some()`. |
33 /// Number of nodes anywhere in the tree that have `.entry.is_some()`. |
31 nodes_with_entry_count: usize, |
34 nodes_with_entry_count: usize, |
32 |
35 |
67 &'a WithBasename<HgPathBuf>, |
70 &'a WithBasename<HgPathBuf>, |
68 &'a mut Option<DirstateEntry>, |
71 &'a mut Option<DirstateEntry>, |
69 &'a mut Option<HgPathBuf>, |
72 &'a mut Option<HgPathBuf>, |
70 ); |
73 ); |
71 |
74 |
72 impl DirstateMap { |
75 impl<'on_disk> DirstateMap<'on_disk> { |
73 pub fn new() -> Self { |
76 pub fn new( |
74 Self { |
77 on_disk: &'on_disk [u8], |
|
78 ) -> Result<(Self, Option<DirstateParents>), DirstateError> { |
|
79 let mut map = Self { |
|
80 on_disk, |
75 root: ChildNodes::default(), |
81 root: ChildNodes::default(), |
76 nodes_with_entry_count: 0, |
82 nodes_with_entry_count: 0, |
77 nodes_with_copy_source_count: 0, |
83 nodes_with_copy_source_count: 0, |
78 } |
84 }; |
|
85 let parents = map.read()?; |
|
86 Ok((map, parents)) |
|
87 } |
|
88 |
|
89 /// Should only be called in `new` |
|
90 #[timed] |
|
91 fn read(&mut self) -> Result<Option<DirstateParents>, DirstateError> { |
|
92 if self.on_disk.is_empty() { |
|
93 return Ok(None); |
|
94 } |
|
95 |
|
96 let parents = parse_dirstate_entries( |
|
97 self.on_disk, |
|
98 |path, entry, copy_source| { |
|
99 let tracked = entry.state.is_tracked(); |
|
100 let node = Self::get_or_insert_node_tracing_ancestors( |
|
101 &mut self.root, |
|
102 path, |
|
103 |ancestor| { |
|
104 if tracked { |
|
105 ancestor.tracked_descendants_count += 1 |
|
106 } |
|
107 }, |
|
108 ); |
|
109 assert!( |
|
110 node.entry.is_none(), |
|
111 "duplicate dirstate entry in read" |
|
112 ); |
|
113 assert!( |
|
114 node.copy_source.is_none(), |
|
115 "duplicate dirstate entry in read" |
|
116 ); |
|
117 node.entry = Some(*entry); |
|
118 node.copy_source = copy_source.map(HgPath::to_owned); |
|
119 self.nodes_with_entry_count += 1; |
|
120 if copy_source.is_some() { |
|
121 self.nodes_with_copy_source_count += 1 |
|
122 } |
|
123 }, |
|
124 )?; |
|
125 |
|
126 Ok(Some(parents.clone())) |
79 } |
127 } |
80 |
128 |
81 fn get_node(&self, path: &HgPath) -> Option<&Node> { |
129 fn get_node(&self, path: &HgPath) -> Option<&Node> { |
82 let mut children = &self.root; |
130 let mut children = &self.root; |
83 let mut components = path.components(); |
131 let mut components = path.components(); |
441 } else { |
489 } else { |
442 Ok(false) |
490 Ok(false) |
443 } |
491 } |
444 } |
492 } |
445 |
493 |
446 #[timed] |
|
447 fn read<'a>( |
|
448 &mut self, |
|
449 file_contents: &'a [u8], |
|
450 ) -> Result<Option<&'a DirstateParents>, DirstateError> { |
|
451 if file_contents.is_empty() { |
|
452 return Ok(None); |
|
453 } |
|
454 |
|
455 let parents = parse_dirstate_entries( |
|
456 file_contents, |
|
457 |path, entry, copy_source| { |
|
458 let tracked = entry.state.is_tracked(); |
|
459 let node = Self::get_or_insert_node_tracing_ancestors( |
|
460 &mut self.root, |
|
461 path, |
|
462 |ancestor| { |
|
463 if tracked { |
|
464 ancestor.tracked_descendants_count += 1 |
|
465 } |
|
466 }, |
|
467 ); |
|
468 assert!( |
|
469 node.entry.is_none(), |
|
470 "duplicate dirstate entry in read" |
|
471 ); |
|
472 assert!( |
|
473 node.copy_source.is_none(), |
|
474 "duplicate dirstate entry in read" |
|
475 ); |
|
476 node.entry = Some(*entry); |
|
477 node.copy_source = copy_source.map(HgPath::to_owned); |
|
478 self.nodes_with_entry_count += 1; |
|
479 if copy_source.is_some() { |
|
480 self.nodes_with_copy_source_count += 1 |
|
481 } |
|
482 }, |
|
483 )?; |
|
484 |
|
485 Ok(Some(parents)) |
|
486 } |
|
487 |
|
488 fn pack( |
494 fn pack( |
489 &mut self, |
495 &mut self, |
490 parents: DirstateParents, |
496 parents: DirstateParents, |
491 now: Timestamp, |
497 now: Timestamp, |
492 ) -> Result<Vec<u8>, DirstateError> { |
498 ) -> Result<Vec<u8>, DirstateError> { |