annotate rust/hg-core/src/dirstate.rs @ 47108:e3cebe96c0fc

dirstate-tree: Add "non normal" and "from other parent" sets Unlike the other DirstateMap implementation, these sets are not materialized separately in memory. Instead we traverse the main tree. Differential Revision: https://phab.mercurial-scm.org/D10492
author Simon Sapin <simon.sapin@octobus.net>
date Fri, 09 Apr 2021 13:13:19 +0200
parents 52906934b775
children be579775c2d9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
42748
7cae6bc29ff9 rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Raphaël Gomès <rgomes@octobus.net>
parents: 42609
diff changeset
1 // dirstate module
7cae6bc29ff9 rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Raphaël Gomès <rgomes@octobus.net>
parents: 42609
diff changeset
2 //
7cae6bc29ff9 rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Raphaël Gomès <rgomes@octobus.net>
parents: 42609
diff changeset
3 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
7cae6bc29ff9 rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Raphaël Gomès <rgomes@octobus.net>
parents: 42609
diff changeset
4 //
7cae6bc29ff9 rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Raphaël Gomès <rgomes@octobus.net>
parents: 42609
diff changeset
5 // This software may be used and distributed according to the terms of the
7cae6bc29ff9 rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Raphaël Gomès <rgomes@octobus.net>
parents: 42609
diff changeset
6 // GNU General Public License version 2 or any later version.
7cae6bc29ff9 rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Raphaël Gomès <rgomes@octobus.net>
parents: 42609
diff changeset
7
46440
776b97179c06 rust: Remove DirstateParseError and ListDirstateTrackedFilesError
Simon Sapin <simon.sapin@octobus.net>
parents: 45610
diff changeset
8 use crate::errors::HgError;
46595
98a455a62699 rust: Make `DirstateParents`’s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46594
diff changeset
9 use crate::revlog::Node;
46440
776b97179c06 rust: Remove DirstateParseError and ListDirstateTrackedFilesError
Simon Sapin <simon.sapin@octobus.net>
parents: 45610
diff changeset
10 use crate::{utils::hg_path::HgPathBuf, FastHashMap};
46594
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
11 use bytes_cast::{unaligned, BytesCast};
42749
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
12 use std::convert::TryFrom;
42748
7cae6bc29ff9 rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Raphaël Gomès <rgomes@octobus.net>
parents: 42609
diff changeset
13
42536
2dcee6497b0b rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 42424
diff changeset
14 pub mod dirs_multiset;
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents: 42749
diff changeset
15 pub mod dirstate_map;
42424
d3b5cbe311d9 rust-dirstate: create dirstate submodule
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
16 pub mod parsers;
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents: 42957
diff changeset
17 pub mod status;
42424
d3b5cbe311d9 rust-dirstate: create dirstate submodule
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
18
46594
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
19 #[derive(Debug, PartialEq, Clone, BytesCast)]
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
20 #[repr(C)]
42748
7cae6bc29ff9 rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Raphaël Gomès <rgomes@octobus.net>
parents: 42609
diff changeset
21 pub struct DirstateParents {
46595
98a455a62699 rust: Make `DirstateParents`’s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46594
diff changeset
22 pub p1: Node,
98a455a62699 rust: Make `DirstateParents`’s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46594
diff changeset
23 pub p2: Node,
42424
d3b5cbe311d9 rust-dirstate: create dirstate submodule
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
24 }
d3b5cbe311d9 rust-dirstate: create dirstate submodule
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
25
d3b5cbe311d9 rust-dirstate: create dirstate submodule
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
26 /// The C implementation uses all signed types. This will be an issue
d3b5cbe311d9 rust-dirstate: create dirstate submodule
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
27 /// either when 4GB+ source files are commonplace or in 2038, whichever
d3b5cbe311d9 rust-dirstate: create dirstate submodule
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
28 /// comes first.
42748
7cae6bc29ff9 rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Raphaël Gomès <rgomes@octobus.net>
parents: 42609
diff changeset
29 #[derive(Debug, PartialEq, Copy, Clone)]
42424
d3b5cbe311d9 rust-dirstate: create dirstate submodule
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
30 pub struct DirstateEntry {
42749
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
31 pub state: EntryState,
42424
d3b5cbe311d9 rust-dirstate: create dirstate submodule
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
32 pub mode: i32,
d3b5cbe311d9 rust-dirstate: create dirstate submodule
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
33 pub mtime: i32,
d3b5cbe311d9 rust-dirstate: create dirstate submodule
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
34 pub size: i32,
d3b5cbe311d9 rust-dirstate: create dirstate submodule
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
35 }
d3b5cbe311d9 rust-dirstate: create dirstate submodule
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
36
47108
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
37 impl DirstateEntry {
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
38 pub fn is_non_normal(&self) -> bool {
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
39 self.state != EntryState::Normal || self.mtime == MTIME_UNSET
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
40 }
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
41
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
42 pub fn is_from_other_parent(&self) -> bool {
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
43 self.state == EntryState::Normal && self.size == SIZE_FROM_OTHER_PARENT
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
44 }
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
45 }
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
46
46594
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
47 #[derive(BytesCast)]
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
48 #[repr(C)]
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
49 struct RawEntry {
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
50 state: u8,
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
51 mode: unaligned::I32Be,
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
52 size: unaligned::I32Be,
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
53 mtime: unaligned::I32Be,
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
54 length: unaligned::I32Be,
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
55 }
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
56
47108
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
57 const MTIME_UNSET: i32 = -1;
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
58
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43271
diff changeset
59 /// A `DirstateEntry` with a size of `-2` means that it was merged from the
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43271
diff changeset
60 /// other parent. This allows revert to pick the right status back during a
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43271
diff changeset
61 /// merge.
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43271
diff changeset
62 pub const SIZE_FROM_OTHER_PARENT: i32 = -2;
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43271
diff changeset
63
43826
5ac243a92e37 rust-performance: introduce FastHashMap type alias for HashMap
Raphaël Gomès <rgomes@octobus.net>
parents: 43605
diff changeset
64 pub type StateMap = FastHashMap<HgPathBuf, DirstateEntry>;
47093
787ff5d21bcd dirstate-tree: Make Rust DirstateMap bindings go through a trait object
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
65 pub type StateMapIter<'a> =
787ff5d21bcd dirstate-tree: Make Rust DirstateMap bindings go through a trait object
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
66 Box<dyn Iterator<Item = (&'a HgPathBuf, &'a DirstateEntry)> + Send + 'a>;
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45609
diff changeset
67
43826
5ac243a92e37 rust-performance: introduce FastHashMap type alias for HashMap
Raphaël Gomès <rgomes@octobus.net>
parents: 43605
diff changeset
68 pub type CopyMap = FastHashMap<HgPathBuf, HgPathBuf>;
47093
787ff5d21bcd dirstate-tree: Make Rust DirstateMap bindings go through a trait object
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
69 pub type CopyMapIter<'a> =
787ff5d21bcd dirstate-tree: Make Rust DirstateMap bindings go through a trait object
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
70 Box<dyn Iterator<Item = (&'a HgPathBuf, &'a HgPathBuf)> + Send + 'a>;
42536
2dcee6497b0b rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 42424
diff changeset
71
42749
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
72 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
73 pub enum EntryState {
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
74 Normal,
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
75 Added,
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
76 Removed,
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
77 Merged,
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
78 Unknown,
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
79 }
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
80
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
81 impl EntryState {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
82 pub fn is_tracked(self) -> bool {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
83 use EntryState::*;
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
84 match self {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
85 Normal | Added | Merged => true,
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
86 Removed | Unknown => false,
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
87 }
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
88 }
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
89 }
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
90
42749
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
91 impl TryFrom<u8> for EntryState {
46440
776b97179c06 rust: Remove DirstateParseError and ListDirstateTrackedFilesError
Simon Sapin <simon.sapin@octobus.net>
parents: 45610
diff changeset
92 type Error = HgError;
42749
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
93
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
94 fn try_from(value: u8) -> Result<Self, Self::Error> {
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
95 match value {
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
96 b'n' => Ok(EntryState::Normal),
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
97 b'a' => Ok(EntryState::Added),
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
98 b'r' => Ok(EntryState::Removed),
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
99 b'm' => Ok(EntryState::Merged),
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
100 b'?' => Ok(EntryState::Unknown),
46440
776b97179c06 rust: Remove DirstateParseError and ListDirstateTrackedFilesError
Simon Sapin <simon.sapin@octobus.net>
parents: 45610
diff changeset
101 _ => Err(HgError::CorruptedRepository(format!(
776b97179c06 rust: Remove DirstateParseError and ListDirstateTrackedFilesError
Simon Sapin <simon.sapin@octobus.net>
parents: 45610
diff changeset
102 "Incorrect dirstate entry state {}",
42749
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
103 value
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
104 ))),
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
105 }
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
106 }
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
107 }
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
108
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
109 impl Into<u8> for EntryState {
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
110 fn into(self) -> u8 {
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
111 match self {
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
112 EntryState::Normal => b'n',
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
113 EntryState::Added => b'a',
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
114 EntryState::Removed => b'r',
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
115 EntryState::Merged => b'm',
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
116 EntryState::Unknown => b'?',
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
117 }
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
118 }
7ceded4419a3 rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents: 42748
diff changeset
119 }