annotate rust/hg-core/src/dirstate_tree/dirstate_map.rs @ 47478:ca8121d26732

dirstate-tree: Keep a counter of descendant nodes that have an entry … and change the `DirstateMap::has_dir` method to be based on this counter being non-zero instead of the mere presence of a node. A node with zero descendent with an entry currently should be removed from the tree, but soon we’ll make the dirstate track additional nodes. (Specifically, for non-ignored directories in order to keep track of their mtime and optimize status by doing fewer `read_dir` calls.) Differential Revision: https://phab.mercurial-scm.org/D10922
author Simon Sapin <simon.sapin@octobus.net>
date Mon, 28 Jun 2021 16:50:19 +0200
parents eb416759af7e
children eaae39894312
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
1 use bytes_cast::BytesCast;
47118
c92e63762573 dirstate-tree: Add #[timed] attribute to `status` and `DirstateMap::read`
Simon Sapin <simon.sapin@octobus.net>
parents: 47116
diff changeset
2 use micro_timer::timed;
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
3 use std::borrow::Cow;
47119
15395fd8ab28 dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47118
diff changeset
4 use std::convert::TryInto;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
5 use std::path::PathBuf;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
6
47283
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
7 use super::on_disk;
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
8 use super::on_disk::DirstateV2ParseError;
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
9 use super::path_with_basename::WithBasename;
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
10 use crate::dirstate::parsers::pack_entry;
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
11 use crate::dirstate::parsers::packed_entry_size;
47098
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
12 use crate::dirstate::parsers::parse_dirstate_entries;
47101
5d62243c7732 rust: Add a Timestamp struct instead of abusing Duration
Simon Sapin <simon.sapin@octobus.net>
parents: 47100
diff changeset
13 use crate::dirstate::parsers::Timestamp;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
14 use crate::matchers::Matcher;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
15 use crate::utils::hg_path::{HgPath, HgPathBuf};
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
16 use crate::CopyMapIter;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
17 use crate::DirstateEntry;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
18 use crate::DirstateError;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
19 use crate::DirstateParents;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
20 use crate::DirstateStatus;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
21 use crate::EntryState;
47119
15395fd8ab28 dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47118
diff changeset
22 use crate::FastHashMap;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
23 use crate::PatternFileWarning;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
24 use crate::StateMapIter;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
25 use crate::StatusError;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
26 use crate::StatusOptions;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
27
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
28 pub struct DirstateMap<'on_disk> {
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
29 /// Contents of the `.hg/dirstate` file
47283
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
30 pub(super) on_disk: &'on_disk [u8],
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
31
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
32 pub(super) root: ChildNodes<'on_disk>,
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
33
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
34 /// Number of nodes anywhere in the tree that have `.entry.is_some()`.
47283
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
35 pub(super) nodes_with_entry_count: u32,
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
36
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
37 /// Number of nodes anywhere in the tree that have
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
38 /// `.copy_source.is_some()`.
47283
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
39 pub(super) nodes_with_copy_source_count: u32,
47409
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47352
diff changeset
40
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47352
diff changeset
41 /// See on_disk::Header
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47352
diff changeset
42 pub(super) ignore_patterns_hash: on_disk::IgnorePatternsHash,
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
43 }
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
44
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
45 /// Using a plain `HgPathBuf` of the full path from the repository root as a
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
46 /// map key would also work: all paths in a given map have the same parent
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
47 /// path, so comparing full paths gives the same result as comparing base
47282
ce41ee53263f dirstate-tree: Extract into a method sorting children of a given node
Simon Sapin <simon.sapin@octobus.net>
parents: 47280
diff changeset
48 /// names. However `HashMap` would waste time always re-hashing the same
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
49 /// string prefix.
47282
ce41ee53263f dirstate-tree: Extract into a method sorting children of a given node
Simon Sapin <simon.sapin@octobus.net>
parents: 47280
diff changeset
50 pub(super) type NodeKey<'on_disk> = WithBasename<Cow<'on_disk, HgPath>>;
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
51
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
52 /// Similar to `&'tree Cow<'on_disk, HgPath>`, but can also be returned
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
53 /// for on-disk nodes that don’t actually have a `Cow` to borrow.
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
54 pub(super) enum BorrowedPath<'tree, 'on_disk> {
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
55 InMemory(&'tree HgPathBuf),
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
56 OnDisk(&'on_disk HgPath),
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
57 }
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
58
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
59 pub(super) enum ChildNodes<'on_disk> {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
60 InMemory(FastHashMap<NodeKey<'on_disk>, Node<'on_disk>>),
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
61 OnDisk(&'on_disk [on_disk::Node]),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
62 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
63
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
64 pub(super) enum ChildNodesRef<'tree, 'on_disk> {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
65 InMemory(&'tree FastHashMap<NodeKey<'on_disk>, Node<'on_disk>>),
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
66 OnDisk(&'on_disk [on_disk::Node]),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
67 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
68
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
69 pub(super) enum NodeRef<'tree, 'on_disk> {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
70 InMemory(&'tree NodeKey<'on_disk>, &'tree Node<'on_disk>),
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
71 OnDisk(&'on_disk on_disk::Node),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
72 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
73
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
74 impl<'tree, 'on_disk> BorrowedPath<'tree, 'on_disk> {
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
75 pub fn detach_from_tree(&self) -> Cow<'on_disk, HgPath> {
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
76 match *self {
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
77 BorrowedPath::InMemory(in_memory) => Cow::Owned(in_memory.clone()),
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
78 BorrowedPath::OnDisk(on_disk) => Cow::Borrowed(on_disk),
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
79 }
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
80 }
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
81 }
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
82
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
83 impl<'tree, 'on_disk> std::ops::Deref for BorrowedPath<'tree, 'on_disk> {
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
84 type Target = HgPath;
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
85
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
86 fn deref(&self) -> &HgPath {
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
87 match *self {
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
88 BorrowedPath::InMemory(in_memory) => in_memory,
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
89 BorrowedPath::OnDisk(on_disk) => on_disk,
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
90 }
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
91 }
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
92 }
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
93
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
94 impl Default for ChildNodes<'_> {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
95 fn default() -> Self {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
96 ChildNodes::InMemory(Default::default())
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
97 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
98 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
99
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
100 impl<'on_disk> ChildNodes<'on_disk> {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
101 pub(super) fn as_ref<'tree>(
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
102 &'tree self,
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
103 ) -> ChildNodesRef<'tree, 'on_disk> {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
104 match self {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
105 ChildNodes::InMemory(nodes) => ChildNodesRef::InMemory(nodes),
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
106 ChildNodes::OnDisk(nodes) => ChildNodesRef::OnDisk(nodes),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
107 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
108 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
109
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
110 pub(super) fn is_empty(&self) -> bool {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
111 match self {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
112 ChildNodes::InMemory(nodes) => nodes.is_empty(),
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
113 ChildNodes::OnDisk(nodes) => nodes.is_empty(),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
114 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
115 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
116
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
117 pub(super) fn make_mut(
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
118 &mut self,
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
119 on_disk: &'on_disk [u8],
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
120 ) -> Result<
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
121 &mut FastHashMap<NodeKey<'on_disk>, Node<'on_disk>>,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
122 DirstateV2ParseError,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
123 > {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
124 match self {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
125 ChildNodes::InMemory(nodes) => Ok(nodes),
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
126 ChildNodes::OnDisk(nodes) => {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
127 let nodes = nodes
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
128 .iter()
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
129 .map(|node| {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
130 Ok((
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
131 node.path(on_disk)?,
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
132 node.to_in_memory_node(on_disk)?,
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
133 ))
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
134 })
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
135 .collect::<Result<_, _>>()?;
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
136 *self = ChildNodes::InMemory(nodes);
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
137 match self {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
138 ChildNodes::InMemory(nodes) => Ok(nodes),
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
139 ChildNodes::OnDisk(_) => unreachable!(),
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
140 }
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
141 }
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
142 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
143 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
144 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
145
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
146 impl<'tree, 'on_disk> ChildNodesRef<'tree, 'on_disk> {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
147 pub(super) fn get(
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
148 &self,
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
149 base_name: &HgPath,
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
150 on_disk: &'on_disk [u8],
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
151 ) -> Result<Option<NodeRef<'tree, 'on_disk>>, DirstateV2ParseError> {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
152 match self {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
153 ChildNodesRef::InMemory(nodes) => Ok(nodes
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
154 .get_key_value(base_name)
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
155 .map(|(k, v)| NodeRef::InMemory(k, v))),
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
156 ChildNodesRef::OnDisk(nodes) => {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
157 let mut parse_result = Ok(());
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
158 let search_result = nodes.binary_search_by(|node| {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
159 match node.base_name(on_disk) {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
160 Ok(node_base_name) => node_base_name.cmp(base_name),
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
161 Err(e) => {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
162 parse_result = Err(e);
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
163 // Dummy comparison result, `search_result` won’t
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
164 // be used since `parse_result` is an error
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
165 std::cmp::Ordering::Equal
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
166 }
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
167 }
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
168 });
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
169 parse_result.map(|()| {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
170 search_result.ok().map(|i| NodeRef::OnDisk(&nodes[i]))
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
171 })
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
172 }
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
173 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
174 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
175
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
176 /// Iterate in undefined order
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
177 pub(super) fn iter(
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
178 &self,
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
179 ) -> impl Iterator<Item = NodeRef<'tree, 'on_disk>> {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
180 match self {
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
181 ChildNodesRef::InMemory(nodes) => itertools::Either::Left(
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
182 nodes.iter().map(|(k, v)| NodeRef::InMemory(k, v)),
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
183 ),
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
184 ChildNodesRef::OnDisk(nodes) => {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
185 itertools::Either::Right(nodes.iter().map(NodeRef::OnDisk))
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
186 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
187 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
188 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
189
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
190 /// Iterate in parallel in undefined order
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
191 pub(super) fn par_iter(
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
192 &self,
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
193 ) -> impl rayon::iter::ParallelIterator<Item = NodeRef<'tree, 'on_disk>>
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
194 {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
195 use rayon::prelude::*;
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
196 match self {
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
197 ChildNodesRef::InMemory(nodes) => rayon::iter::Either::Left(
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
198 nodes.par_iter().map(|(k, v)| NodeRef::InMemory(k, v)),
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
199 ),
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
200 ChildNodesRef::OnDisk(nodes) => rayon::iter::Either::Right(
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
201 nodes.par_iter().map(NodeRef::OnDisk),
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
202 ),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
203 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
204 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
205
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
206 pub(super) fn sorted(&self) -> Vec<NodeRef<'tree, 'on_disk>> {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
207 match self {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
208 ChildNodesRef::InMemory(nodes) => {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
209 let mut vec: Vec<_> = nodes
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
210 .iter()
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
211 .map(|(k, v)| NodeRef::InMemory(k, v))
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
212 .collect();
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
213 fn sort_key<'a>(node: &'a NodeRef) -> &'a HgPath {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
214 match node {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
215 NodeRef::InMemory(path, _node) => path.base_name(),
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
216 NodeRef::OnDisk(_) => unreachable!(),
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
217 }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
218 }
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
219 // `sort_unstable_by_key` doesn’t allow keys borrowing from the
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
220 // value: https://github.com/rust-lang/rust/issues/34162
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
221 vec.sort_unstable_by(|a, b| sort_key(a).cmp(sort_key(b)));
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
222 vec
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
223 }
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
224 ChildNodesRef::OnDisk(nodes) => {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
225 // Nodes on disk are already sorted
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
226 nodes.iter().map(NodeRef::OnDisk).collect()
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
227 }
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
228 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
229 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
230 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
231
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
232 impl<'tree, 'on_disk> NodeRef<'tree, 'on_disk> {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
233 pub(super) fn full_path(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
234 &self,
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
235 on_disk: &'on_disk [u8],
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
236 ) -> Result<&'tree HgPath, DirstateV2ParseError> {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
237 match self {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
238 NodeRef::InMemory(path, _node) => Ok(path.full_path()),
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
239 NodeRef::OnDisk(node) => node.full_path(on_disk),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
240 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
241 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
242
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
243 /// Returns a `BorrowedPath`, which can be turned into a `Cow<'on_disk,
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
244 /// HgPath>` detached from `'tree`
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
245 pub(super) fn full_path_borrowed(
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
246 &self,
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
247 on_disk: &'on_disk [u8],
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
248 ) -> Result<BorrowedPath<'tree, 'on_disk>, DirstateV2ParseError> {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
249 match self {
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
250 NodeRef::InMemory(path, _node) => match path.full_path() {
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
251 Cow::Borrowed(on_disk) => Ok(BorrowedPath::OnDisk(on_disk)),
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
252 Cow::Owned(in_memory) => Ok(BorrowedPath::InMemory(in_memory)),
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
253 },
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
254 NodeRef::OnDisk(node) => {
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
255 Ok(BorrowedPath::OnDisk(node.full_path(on_disk)?))
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
256 }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
257 }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
258 }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
259
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
260 pub(super) fn base_name(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
261 &self,
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
262 on_disk: &'on_disk [u8],
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
263 ) -> Result<&'tree HgPath, DirstateV2ParseError> {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
264 match self {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
265 NodeRef::InMemory(path, _node) => Ok(path.base_name()),
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
266 NodeRef::OnDisk(node) => node.base_name(on_disk),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
267 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
268 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
269
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
270 pub(super) fn children(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
271 &self,
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
272 on_disk: &'on_disk [u8],
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
273 ) -> Result<ChildNodesRef<'tree, 'on_disk>, DirstateV2ParseError> {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
274 match self {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
275 NodeRef::InMemory(_path, node) => Ok(node.children.as_ref()),
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
276 NodeRef::OnDisk(node) => {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
277 Ok(ChildNodesRef::OnDisk(node.children(on_disk)?))
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
278 }
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
279 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
280 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
281
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
282 pub(super) fn has_copy_source(&self) -> bool {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
283 match self {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
284 NodeRef::InMemory(_path, node) => node.copy_source.is_some(),
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
285 NodeRef::OnDisk(node) => node.has_copy_source(),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
286 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
287 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
288
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
289 pub(super) fn copy_source(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
290 &self,
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
291 on_disk: &'on_disk [u8],
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
292 ) -> Result<Option<&'tree HgPath>, DirstateV2ParseError> {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
293 match self {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
294 NodeRef::InMemory(_path, node) => {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
295 Ok(node.copy_source.as_ref().map(|s| &**s))
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
296 }
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
297 NodeRef::OnDisk(node) => node.copy_source(on_disk),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
298 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
299 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
300
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
301 pub(super) fn entry(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
302 &self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
303 ) -> Result<Option<DirstateEntry>, DirstateV2ParseError> {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
304 match self {
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
305 NodeRef::InMemory(_path, node) => {
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
306 Ok(node.data.as_entry().copied())
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
307 }
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
308 NodeRef::OnDisk(node) => node.entry(),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
309 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
310 }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
311
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
312 pub(super) fn state(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
313 &self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
314 ) -> Result<Option<EntryState>, DirstateV2ParseError> {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
315 match self {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
316 NodeRef::InMemory(_path, node) => {
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
317 Ok(node.data.as_entry().map(|entry| entry.state))
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
318 }
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
319 NodeRef::OnDisk(node) => node.state(),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
320 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
321 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
322
47349
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
323 pub(super) fn cached_directory_mtime(
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
324 &self,
47351
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
325 ) -> Option<&'tree on_disk::Timestamp> {
47349
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
326 match self {
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
327 NodeRef::InMemory(_path, node) => match &node.data {
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
328 NodeData::CachedDirectory { mtime } => Some(mtime),
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
329 _ => None,
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
330 },
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
331 NodeRef::OnDisk(node) => node.cached_directory_mtime(),
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
332 }
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
333 }
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
334
47478
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
335 pub(super) fn descendants_with_entry_count(&self) -> u32 {
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
336 match self {
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
337 NodeRef::InMemory(_path, node) => {
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
338 node.descendants_with_entry_count
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
339 }
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
340 NodeRef::OnDisk(node) => node.descendants_with_entry_count.get(),
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
341 }
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
342 }
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
343
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
344 pub(super) fn tracked_descendants_count(&self) -> u32 {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
345 match self {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
346 NodeRef::InMemory(_path, node) => node.tracked_descendants_count,
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
347 NodeRef::OnDisk(node) => node.tracked_descendants_count.get(),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
348 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
349 }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
350 }
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
351
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
352 /// Represents a file or a directory
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
353 #[derive(Default)]
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
354 pub(super) struct Node<'on_disk> {
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
355 pub(super) data: NodeData,
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
356
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
357 pub(super) copy_source: Option<Cow<'on_disk, HgPath>>,
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
358
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
359 pub(super) children: ChildNodes<'on_disk>,
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
360
47478
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
361 /// How many (non-inclusive) descendants of this node have an entry.
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
362 pub(super) descendants_with_entry_count: u32,
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
363
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
364 /// How many (non-inclusive) descendants of this node have an entry whose
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
365 /// state is "tracked".
47283
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
366 pub(super) tracked_descendants_count: u32,
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
367 }
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
368
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
369 pub(super) enum NodeData {
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
370 Entry(DirstateEntry),
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
371 CachedDirectory { mtime: on_disk::Timestamp },
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
372 None,
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
373 }
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
374
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
375 impl Default for NodeData {
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
376 fn default() -> Self {
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
377 NodeData::None
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
378 }
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
379 }
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
380
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
381 impl NodeData {
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
382 fn has_entry(&self) -> bool {
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
383 match self {
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
384 NodeData::Entry(_) => true,
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
385 _ => false,
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
386 }
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
387 }
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
388
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
389 fn as_entry(&self) -> Option<&DirstateEntry> {
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
390 match self {
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
391 NodeData::Entry(entry) => Some(entry),
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
392 _ => None,
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
393 }
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
394 }
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
395 }
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
396
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
397 impl<'on_disk> DirstateMap<'on_disk> {
47283
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
398 pub(super) fn empty(on_disk: &'on_disk [u8]) -> Self {
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
399 Self {
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
400 on_disk,
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
401 root: ChildNodes::default(),
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
402 nodes_with_entry_count: 0,
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
403 nodes_with_copy_source_count: 0,
47409
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47352
diff changeset
404 ignore_patterns_hash: [0; on_disk::IGNORE_PATTERNS_HASH_LEN],
47283
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
405 }
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
406 }
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
407
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
408 #[timed]
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
409 pub fn new_v2(
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
410 on_disk: &'on_disk [u8],
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
411 ) -> Result<(Self, Option<DirstateParents>), DirstateError> {
47334
18b3060fe598 dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents: 47333
diff changeset
412 Ok(on_disk::read(on_disk)?)
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
413 }
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
414
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
415 #[timed]
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
416 pub fn new_v1(
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
417 on_disk: &'on_disk [u8],
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
418 ) -> Result<(Self, Option<DirstateParents>), DirstateError> {
47283
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
419 let mut map = Self::empty(on_disk);
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
420 if map.on_disk.is_empty() {
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
421 return Ok((map, None));
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
422 }
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
423
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
424 let parents = parse_dirstate_entries(
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
425 map.on_disk,
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
426 |path, entry, copy_source| {
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
427 let tracked = entry.state.is_tracked();
47126
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
428 let node = Self::get_or_insert_node(
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
429 map.on_disk,
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
430 &mut map.root,
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
431 path,
47126
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
432 WithBasename::to_cow_borrowed,
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
433 |ancestor| {
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
434 if tracked {
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
435 ancestor.tracked_descendants_count += 1
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
436 }
47478
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
437 ancestor.descendants_with_entry_count += 1
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
438 },
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
439 )?;
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
440 assert!(
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
441 !node.data.has_entry(),
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
442 "duplicate dirstate entry in read"
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
443 );
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
444 assert!(
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
445 node.copy_source.is_none(),
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
446 "duplicate dirstate entry in read"
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
447 );
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
448 node.data = NodeData::Entry(*entry);
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
449 node.copy_source = copy_source.map(Cow::Borrowed);
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
450 map.nodes_with_entry_count += 1;
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
451 if copy_source.is_some() {
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
452 map.nodes_with_copy_source_count += 1
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
453 }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
454 Ok(())
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
455 },
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
456 )?;
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
457 let parents = Some(parents.clone());
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
458
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
459 Ok((map, parents))
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
460 }
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
461
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
462 fn get_node<'tree>(
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
463 &'tree self,
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
464 path: &HgPath,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
465 ) -> Result<Option<NodeRef<'tree, 'on_disk>>, DirstateV2ParseError> {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
466 let mut children = self.root.as_ref();
47099
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
467 let mut components = path.components();
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
468 let mut component =
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
469 components.next().expect("expected at least one components");
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
470 loop {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
471 if let Some(child) = children.get(component, self.on_disk)? {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
472 if let Some(next_component) = components.next() {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
473 component = next_component;
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
474 children = child.children(self.on_disk)?;
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
475 } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
476 return Ok(Some(child));
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
477 }
47099
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
478 } else {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
479 return Ok(None);
47099
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
480 }
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
481 }
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
482 }
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
483
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
484 /// Returns a mutable reference to the node at `path` if it exists
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
485 ///
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
486 /// This takes `root` instead of `&mut self` so that callers can mutate
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
487 /// other fields while the returned borrow is still valid
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
488 fn get_node_mut<'tree>(
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
489 on_disk: &'on_disk [u8],
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
490 root: &'tree mut ChildNodes<'on_disk>,
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
491 path: &HgPath,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
492 ) -> Result<Option<&'tree mut Node<'on_disk>>, DirstateV2ParseError> {
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
493 let mut children = root;
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
494 let mut components = path.components();
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
495 let mut component =
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
496 components.next().expect("expected at least one components");
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
497 loop {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
498 if let Some(child) = children.make_mut(on_disk)?.get_mut(component)
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
499 {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
500 if let Some(next_component) = components.next() {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
501 component = next_component;
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
502 children = &mut child.children;
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
503 } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
504 return Ok(Some(child));
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
505 }
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
506 } else {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
507 return Ok(None);
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
508 }
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
509 }
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
510 }
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
511
47474
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
512 pub(super) fn get_or_insert<'tree, 'path>(
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
513 &'tree mut self,
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
514 path: &HgPath,
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
515 ) -> Result<&'tree mut Node<'on_disk>, DirstateV2ParseError> {
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
516 Self::get_or_insert_node(
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
517 self.on_disk,
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
518 &mut self.root,
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
519 path,
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
520 WithBasename::to_cow_owned,
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
521 |_| {},
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
522 )
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
523 }
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
524
47349
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
525 pub(super) fn get_or_insert_node<'tree, 'path>(
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
526 on_disk: &'on_disk [u8],
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
527 root: &'tree mut ChildNodes<'on_disk>,
47126
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
528 path: &'path HgPath,
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
529 to_cow: impl Fn(
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
530 WithBasename<&'path HgPath>,
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
531 ) -> WithBasename<Cow<'on_disk, HgPath>>,
47120
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
532 mut each_ancestor: impl FnMut(&mut Node),
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
533 ) -> Result<&'tree mut Node<'on_disk>, DirstateV2ParseError> {
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
534 let mut child_nodes = root;
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
535 let mut inclusive_ancestor_paths =
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
536 WithBasename::inclusive_ancestors_of(path);
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
537 let mut ancestor_path = inclusive_ancestor_paths
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
538 .next()
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
539 .expect("expected at least one inclusive ancestor");
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
540 loop {
47116
04bcba539c96 dirstate-tree: Avoid BTreeMap double-lookup when inserting a dirstate entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47113
diff changeset
541 // TODO: can we avoid allocating an owned key in cases where the
04bcba539c96 dirstate-tree: Avoid BTreeMap double-lookup when inserting a dirstate entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47113
diff changeset
542 // map already contains that key, without introducing double
04bcba539c96 dirstate-tree: Avoid BTreeMap double-lookup when inserting a dirstate entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47113
diff changeset
543 // lookup?
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
544 let child_node = child_nodes
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
545 .make_mut(on_disk)?
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
546 .entry(to_cow(ancestor_path))
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
547 .or_default();
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
548 if let Some(next) = inclusive_ancestor_paths.next() {
47120
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
549 each_ancestor(child_node);
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
550 ancestor_path = next;
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
551 child_nodes = &mut child_node.children;
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
552 } else {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
553 return Ok(child_node);
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
554 }
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
555 }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
556 }
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
557
47120
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
558 fn add_or_remove_file(
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
559 &mut self,
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
560 path: &HgPath,
47120
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
561 old_state: EntryState,
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
562 new_entry: DirstateEntry,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
563 ) -> Result<(), DirstateV2ParseError> {
47478
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
564 let had_entry = old_state != EntryState::Unknown;
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
565 let tracked_count_increment =
47120
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
566 match (old_state.is_tracked(), new_entry.state.is_tracked()) {
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
567 (false, true) => 1,
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
568 (true, false) => -1,
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
569 _ => 0,
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
570 };
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
571
47126
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
572 let node = Self::get_or_insert_node(
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
573 self.on_disk,
47120
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
574 &mut self.root,
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
575 path,
47126
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
576 WithBasename::to_cow_owned,
47120
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
577 |ancestor| {
47478
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
578 if !had_entry {
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
579 ancestor.descendants_with_entry_count += 1;
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
580 }
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
581
47120
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
582 // We can’t use `+= increment` because the counter is unsigned,
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
583 // and we want debug builds to detect accidental underflow
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
584 // through zero
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
585 match tracked_count_increment {
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
586 1 => ancestor.tracked_descendants_count += 1,
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
587 -1 => ancestor.tracked_descendants_count -= 1,
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
588 _ => {}
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
589 }
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
590 },
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
591 )?;
47478
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
592 if !had_entry {
47120
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
593 self.nodes_with_entry_count += 1
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
594 }
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
595 node.data = NodeData::Entry(new_entry);
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
596 Ok(())
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
597 }
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
598
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
599 fn iter_nodes<'tree>(
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
600 &'tree self,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
601 ) -> impl Iterator<
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
602 Item = Result<NodeRef<'tree, 'on_disk>, DirstateV2ParseError>,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
603 > + 'tree {
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
604 // Depth first tree traversal.
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
605 //
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
606 // If we could afford internal iteration and recursion,
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
607 // this would look like:
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
608 //
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
609 // ```
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
610 // fn traverse_children(
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
611 // children: &ChildNodes,
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
612 // each: &mut impl FnMut(&Node),
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
613 // ) {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
614 // for child in children.values() {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
615 // traverse_children(&child.children, each);
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
616 // each(child);
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
617 // }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
618 // }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
619 // ```
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
620 //
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
621 // However we want an external iterator and therefore can’t use the
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
622 // call stack. Use an explicit stack instead:
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
623 let mut stack = Vec::new();
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
624 let mut iter = self.root.as_ref().iter();
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
625 std::iter::from_fn(move || {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
626 while let Some(child_node) = iter.next() {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
627 let children = match child_node.children(self.on_disk) {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
628 Ok(children) => children,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
629 Err(error) => return Some(Err(error)),
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
630 };
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
631 // Pseudo-recursion
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
632 let new_iter = children.iter();
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
633 let old_iter = std::mem::replace(&mut iter, new_iter);
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
634 stack.push((child_node, old_iter));
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
635 }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
636 // Found the end of a `children.iter()` iterator.
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
637 if let Some((child_node, next_iter)) = stack.pop() {
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
638 // "Return" from pseudo-recursion by restoring state from the
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
639 // explicit stack
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
640 iter = next_iter;
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
641
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
642 Some(Ok(child_node))
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
643 } else {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
644 // Reached the bottom of the stack, we’re done
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
645 None
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
646 }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
647 })
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
648 }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
649
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
650 fn clear_known_ambiguous_mtimes(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
651 &mut self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
652 paths: &[impl AsRef<HgPath>],
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
653 ) -> Result<(), DirstateV2ParseError> {
47330
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
654 for path in paths {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
655 if let Some(node) = Self::get_node_mut(
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
656 self.on_disk,
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
657 &mut self.root,
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
658 path.as_ref(),
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
659 )? {
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
660 if let NodeData::Entry(entry) = &mut node.data {
47330
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
661 entry.clear_mtime();
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
662 }
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
663 }
47330
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
664 }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
665 Ok(())
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
666 }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
667
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
668 /// Return a faillilble iterator of full paths of nodes that have an
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
669 /// `entry` for which the given `predicate` returns true.
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
670 ///
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
671 /// Fallibility means that each iterator item is a `Result`, which may
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
672 /// indicate a parse error of the on-disk dirstate-v2 format. Such errors
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
673 /// should only happen if Mercurial is buggy or a repository is corrupted.
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
674 fn filter_full_paths<'tree>(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
675 &'tree self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
676 predicate: impl Fn(&DirstateEntry) -> bool + 'tree,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
677 ) -> impl Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + 'tree
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
678 {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
679 filter_map_results(self.iter_nodes(), move |node| {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
680 if let Some(entry) = node.entry()? {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
681 if predicate(&entry) {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
682 return Ok(Some(node.full_path(self.on_disk)?));
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
683 }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
684 }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
685 Ok(None)
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
686 })
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
687 }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
688 }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
689
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
690 /// Like `Iterator::filter_map`, but over a fallible iterator of `Result`s.
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
691 ///
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
692 /// The callback is only called for incoming `Ok` values. Errors are passed
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
693 /// through as-is. In order to let it use the `?` operator the callback is
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
694 /// expected to return a `Result` of `Option`, instead of an `Option` of
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
695 /// `Result`.
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
696 fn filter_map_results<'a, I, F, A, B, E>(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
697 iter: I,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
698 f: F,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
699 ) -> impl Iterator<Item = Result<B, E>> + 'a
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
700 where
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
701 I: Iterator<Item = Result<A, E>> + 'a,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
702 F: Fn(A) -> Result<Option<B>, E> + 'a,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
703 {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
704 iter.filter_map(move |result| match result {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
705 Ok(node) => f(node).transpose(),
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
706 Err(e) => Some(Err(e)),
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
707 })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
708 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
709
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
710 impl<'on_disk> super::dispatch::DirstateMapMethods for DirstateMap<'on_disk> {
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
711 fn clear(&mut self) {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
712 self.root = Default::default();
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
713 self.nodes_with_entry_count = 0;
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
714 self.nodes_with_copy_source_count = 0;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
715 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
716
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
717 fn add_file(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
718 &mut self,
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
719 filename: &HgPath,
47120
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
720 old_state: EntryState,
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
721 entry: DirstateEntry,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
722 ) -> Result<(), DirstateError> {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
723 Ok(self.add_or_remove_file(filename, old_state, entry)?)
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
724 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
725
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
726 fn remove_file(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
727 &mut self,
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
728 filename: &HgPath,
47120
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
729 old_state: EntryState,
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
730 size: i32,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
731 ) -> Result<(), DirstateError> {
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
732 let entry = DirstateEntry {
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
733 state: EntryState::Removed,
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
734 mode: 0,
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
735 size,
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
736 mtime: 0,
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
737 };
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
738 Ok(self.add_or_remove_file(filename, old_state, entry)?)
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
739 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
740
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
741 fn drop_file(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
742 &mut self,
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
743 filename: &HgPath,
47120
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
744 old_state: EntryState,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
745 ) -> Result<bool, DirstateError> {
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
746 struct Dropped {
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
747 was_tracked: bool,
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
748 had_entry: bool,
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
749 had_copy_source: bool,
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
750 }
47352
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
751
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
752 /// If this returns `Ok(Some((dropped, removed)))`, then
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
753 ///
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
754 /// * `dropped` is about the leaf node that was at `filename`
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
755 /// * `removed` is whether this particular level of recursion just
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
756 /// removed a node in `nodes`.
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
757 fn recur<'on_disk>(
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
758 on_disk: &'on_disk [u8],
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
759 nodes: &mut ChildNodes<'on_disk>,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
760 path: &HgPath,
47352
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
761 ) -> Result<Option<(Dropped, bool)>, DirstateV2ParseError> {
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
762 let (first_path_component, rest_of_path) =
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
763 path.split_first_component();
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
764 let node = if let Some(node) =
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
765 nodes.make_mut(on_disk)?.get_mut(first_path_component)
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
766 {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
767 node
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
768 } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
769 return Ok(None);
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
770 };
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
771 let dropped;
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
772 if let Some(rest) = rest_of_path {
47352
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
773 if let Some((d, removed)) =
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
774 recur(on_disk, &mut node.children, rest)?
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
775 {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
776 dropped = d;
47478
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
777 if dropped.had_entry {
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
778 node.descendants_with_entry_count -= 1;
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
779 }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
780 if dropped.was_tracked {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
781 node.tracked_descendants_count -= 1;
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
782 }
47352
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
783
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
784 // Directory caches must be invalidated when removing a
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
785 // child node
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
786 if removed {
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
787 if let NodeData::CachedDirectory { .. } = &node.data {
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
788 node.data = NodeData::None
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
789 }
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
790 }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
791 } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
792 return Ok(None);
47120
7109a38830c9 dirstate-tree: Fold "tracked descendants" counter update in main walk
Simon Sapin <simon.sapin@octobus.net>
parents: 47119
diff changeset
793 }
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
794 } else {
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
795 let had_entry = node.data.has_entry();
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
796 if had_entry {
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
797 node.data = NodeData::None
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
798 }
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
799 dropped = Dropped {
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
800 was_tracked: node
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
801 .data
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
802 .as_entry()
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
803 .map_or(false, |entry| entry.state.is_tracked()),
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
804 had_entry,
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
805 had_copy_source: node.copy_source.take().is_some(),
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
806 };
47193
47ccab19bf9f dirstate-tree: Remove newly-empty nodes after removing a `DirstateEntry`
Simon Sapin <simon.sapin@octobus.net>
parents: 47192
diff changeset
807 }
47ccab19bf9f dirstate-tree: Remove newly-empty nodes after removing a `DirstateEntry`
Simon Sapin <simon.sapin@octobus.net>
parents: 47192
diff changeset
808 // After recursion, for both leaf (rest_of_path is None) nodes and
47ccab19bf9f dirstate-tree: Remove newly-empty nodes after removing a `DirstateEntry`
Simon Sapin <simon.sapin@octobus.net>
parents: 47192
diff changeset
809 // parent nodes, remove a node if it just became empty.
47352
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
810 let remove = !node.data.has_entry()
47193
47ccab19bf9f dirstate-tree: Remove newly-empty nodes after removing a `DirstateEntry`
Simon Sapin <simon.sapin@octobus.net>
parents: 47192
diff changeset
811 && node.copy_source.is_none()
47352
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
812 && node.children.is_empty();
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
813 if remove {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
814 nodes.make_mut(on_disk)?.remove(first_path_component);
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
815 }
47352
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
816 Ok(Some((dropped, remove)))
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
817 }
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
818
47352
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
819 if let Some((dropped, _removed)) =
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
820 recur(self.on_disk, &mut self.root, filename)?
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
821 {
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
822 if dropped.had_entry {
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
823 self.nodes_with_entry_count -= 1
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
824 }
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
825 if dropped.had_copy_source {
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
826 self.nodes_with_copy_source_count -= 1
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
827 }
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
828 Ok(dropped.had_entry)
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
829 } else {
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
830 debug_assert!(!old_state.is_tracked());
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
831 Ok(false)
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
832 }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
833 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
834
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
835 fn clear_ambiguous_times(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
836 &mut self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
837 filenames: Vec<HgPathBuf>,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
838 now: i32,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
839 ) -> Result<(), DirstateV2ParseError> {
47105
ba17a2ee85ac dirstate-tree: Add clear_ambiguous_times in the new DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47104
diff changeset
840 for filename in filenames {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
841 if let Some(node) =
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
842 Self::get_node_mut(self.on_disk, &mut self.root, &filename)?
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
843 {
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
844 if let NodeData::Entry(entry) = &mut node.data {
47330
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
845 entry.clear_ambiguous_mtime(now);
47105
ba17a2ee85ac dirstate-tree: Add clear_ambiguous_times in the new DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47104
diff changeset
846 }
ba17a2ee85ac dirstate-tree: Add clear_ambiguous_times in the new DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47104
diff changeset
847 }
ba17a2ee85ac dirstate-tree: Add clear_ambiguous_times in the new DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47104
diff changeset
848 }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
849 Ok(())
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
850 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
851
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
852 fn non_normal_entries_contains(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
853 &mut self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
854 key: &HgPath,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
855 ) -> Result<bool, DirstateV2ParseError> {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
856 Ok(if let Some(node) = self.get_node(key)? {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
857 node.entry()?.map_or(false, |entry| entry.is_non_normal())
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
858 } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
859 false
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
860 })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
861 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
862
47108
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
863 fn non_normal_entries_remove(&mut self, _key: &HgPath) {
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
864 // Do nothing, this `DirstateMap` does not have a separate "non normal
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
865 // entries" set that need to be kept up to date
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
866 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
867
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
868 fn non_normal_or_other_parent_paths(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
869 &mut self,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
870 ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_>
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
871 {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
872 Box::new(self.filter_full_paths(|entry| {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
873 entry.is_non_normal() || entry.is_from_other_parent()
47108
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
874 }))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
875 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
876
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
877 fn set_non_normal_other_parent_entries(&mut self, _force: bool) {
47108
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
878 // Do nothing, this `DirstateMap` does not have a separate "non normal
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
879 // entries" and "from other parent" sets that need to be recomputed
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
880 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
881
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
882 fn iter_non_normal_paths(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
883 &mut self,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
884 ) -> Box<
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
885 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
886 > {
47108
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
887 self.iter_non_normal_paths_panic()
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
888 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
889
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
890 fn iter_non_normal_paths_panic(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
891 &self,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
892 ) -> Box<
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
893 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
894 > {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
895 Box::new(self.filter_full_paths(|entry| entry.is_non_normal()))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
896 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
897
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
898 fn iter_other_parent_paths(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
899 &mut self,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
900 ) -> Box<
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
901 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
902 > {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
903 Box::new(self.filter_full_paths(|entry| entry.is_from_other_parent()))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
904 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
905
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
906 fn has_tracked_dir(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
907 &mut self,
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
908 directory: &HgPath,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
909 ) -> Result<bool, DirstateError> {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
910 if let Some(node) = self.get_node(directory)? {
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
911 // A node without a `DirstateEntry` was created to hold child
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
912 // nodes, and is therefore a directory.
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
913 let state = node.state()?;
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
914 Ok(state.is_none() && node.tracked_descendants_count() > 0)
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
915 } else {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
916 Ok(false)
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
917 }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
918 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
919
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
920 fn has_dir(&mut self, directory: &HgPath) -> Result<bool, DirstateError> {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
921 if let Some(node) = self.get_node(directory)? {
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
922 // A node without a `DirstateEntry` was created to hold child
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
923 // nodes, and is therefore a directory.
47478
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
924 let state = node.state()?;
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
925 Ok(state.is_none() && node.descendants_with_entry_count() > 0)
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
926 } else {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
927 Ok(false)
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
928 }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
929 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
930
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
931 #[timed]
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
932 fn pack_v1(
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
933 &mut self,
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
934 parents: DirstateParents,
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
935 now: Timestamp,
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
936 ) -> Result<Vec<u8>, DirstateError> {
47330
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
937 let now: i32 = now.0.try_into().expect("time overflow");
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
938 let mut ambiguous_mtimes = Vec::new();
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
939 // Optizimation (to be measured?): pre-compute size to avoid `Vec`
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
940 // reallocations
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
941 let mut size = parents.as_bytes().len();
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
942 for node in self.iter_nodes() {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
943 let node = node?;
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
944 if let Some(entry) = node.entry()? {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
945 size += packed_entry_size(
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
946 node.full_path(self.on_disk)?,
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
947 node.copy_source(self.on_disk)?,
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
948 );
47330
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
949 if entry.mtime_is_ambiguous(now) {
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
950 ambiguous_mtimes.push(
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
951 node.full_path_borrowed(self.on_disk)?
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
952 .detach_from_tree(),
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
953 )
47330
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
954 }
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
955 }
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
956 }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
957 self.clear_known_ambiguous_mtimes(&ambiguous_mtimes)?;
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
958
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
959 let mut packed = Vec::with_capacity(size);
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
960 packed.extend(parents.as_bytes());
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
961
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
962 for node in self.iter_nodes() {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
963 let node = node?;
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
964 if let Some(entry) = node.entry()? {
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
965 pack_entry(
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
966 node.full_path(self.on_disk)?,
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
967 &entry,
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
968 node.copy_source(self.on_disk)?,
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
969 &mut packed,
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
970 );
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
971 }
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
972 }
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
973 Ok(packed)
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
974 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
975
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
976 #[timed]
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
977 fn pack_v2(
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
978 &mut self,
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
979 parents: DirstateParents,
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
980 now: Timestamp,
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
981 ) -> Result<Vec<u8>, DirstateError> {
47330
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
982 // TODO: how do we want to handle this in 2038?
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
983 let now: i32 = now.0.try_into().expect("time overflow");
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
984 let mut paths = Vec::new();
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
985 for node in self.iter_nodes() {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
986 let node = node?;
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
987 if let Some(entry) = node.entry()? {
47330
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
988 if entry.mtime_is_ambiguous(now) {
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
989 paths.push(
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
990 node.full_path_borrowed(self.on_disk)?
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
991 .detach_from_tree(),
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
992 )
47330
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
993 }
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
994 }
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
995 }
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
996 // Borrow of `self` ends here since we collect cloned paths
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
997
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
998 self.clear_known_ambiguous_mtimes(&paths)?;
47330
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
999
73f23e7610f8 dirstate-tree: Remove DirstateMap::iter_node_data_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 47283
diff changeset
1000 on_disk::write(self, parents)
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
1001 }
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
1002
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1003 fn status<'a>(
47112
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
1004 &'a mut self,
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
1005 matcher: &'a (dyn Matcher + Sync),
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
1006 root_dir: PathBuf,
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
1007 ignore_files: Vec<PathBuf>,
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
1008 options: StatusOptions,
47110
9c6b458a08e1 rust: Move "lookup" a.k.a. "unsure" paths into `DirstateStatus` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47109
diff changeset
1009 ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>
9c6b458a08e1 rust: Move "lookup" a.k.a. "unsure" paths into `DirstateStatus` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47109
diff changeset
1010 {
47112
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
1011 super::status::status(self, matcher, root_dir, ignore_files, options)
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1012 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1013
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1014 fn copy_map_len(&self) -> usize {
47283
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
1015 self.nodes_with_copy_source_count as usize
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1016 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1017
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1018 fn copy_map_iter(&self) -> CopyMapIter<'_> {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1019 Box::new(filter_map_results(self.iter_nodes(), move |node| {
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1020 Ok(if let Some(source) = node.copy_source(self.on_disk)? {
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1021 Some((node.full_path(self.on_disk)?, source))
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1022 } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1023 None
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1024 })
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
1025 }))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1026 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1027
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1028 fn copy_map_contains_key(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1029 &self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1030 key: &HgPath,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1031 ) -> Result<bool, DirstateV2ParseError> {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1032 Ok(if let Some(node) = self.get_node(key)? {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1033 node.has_copy_source()
47099
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
1034 } else {
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
1035 false
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1036 })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1037 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1038
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1039 fn copy_map_get(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1040 &self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1041 key: &HgPath,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1042 ) -> Result<Option<&HgPath>, DirstateV2ParseError> {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1043 if let Some(node) = self.get_node(key)? {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1044 if let Some(source) = node.copy_source(self.on_disk)? {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1045 return Ok(Some(source));
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1046 }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1047 }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1048 Ok(None)
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1049 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1050
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1051 fn copy_map_remove(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1052 &mut self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1053 key: &HgPath,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1054 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> {
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
1055 let count = &mut self.nodes_with_copy_source_count;
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1056 Ok(
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1057 Self::get_node_mut(self.on_disk, &mut self.root, key)?.and_then(
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1058 |node| {
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1059 if node.copy_source.is_some() {
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1060 *count -= 1
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1061 }
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1062 node.copy_source.take().map(Cow::into_owned)
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1063 },
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1064 ),
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1065 )
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1066 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1067
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1068 fn copy_map_insert(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1069 &mut self,
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
1070 key: HgPathBuf,
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
1071 value: HgPathBuf,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1072 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> {
47126
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
1073 let node = Self::get_or_insert_node(
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1074 self.on_disk,
47126
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
1075 &mut self.root,
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
1076 &key,
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
1077 WithBasename::to_cow_owned,
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
1078 |_ancestor| {},
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1079 )?;
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
1080 if node.copy_source.is_none() {
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
1081 self.nodes_with_copy_source_count += 1
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
1082 }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1083 Ok(node.copy_source.replace(value.into()).map(Cow::into_owned))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1084 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1085
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1086 fn len(&self) -> usize {
47283
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
1087 self.nodes_with_entry_count as usize
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1088 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1089
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1090 fn contains_key(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1091 &self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1092 key: &HgPath,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1093 ) -> Result<bool, DirstateV2ParseError> {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1094 Ok(self.get(key)?.is_some())
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1095 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1096
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1097 fn get(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1098 &self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1099 key: &HgPath,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1100 ) -> Result<Option<DirstateEntry>, DirstateV2ParseError> {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1101 Ok(if let Some(node) = self.get_node(key)? {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1102 node.entry()?
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1103 } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1104 None
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1105 })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1106 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1107
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1108 fn iter(&self) -> StateMapIter<'_> {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1109 Box::new(filter_map_results(self.iter_nodes(), move |node| {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1110 Ok(if let Some(entry) = node.entry()? {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
1111 Some((node.full_path(self.on_disk)?, entry))
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1112 } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1113 None
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
1114 })
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
1115 }))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1116 }
47351
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1117
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1118 fn iter_directories(
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1119 &self,
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1120 ) -> Box<
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1121 dyn Iterator<
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1122 Item = Result<
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1123 (&HgPath, Option<Timestamp>),
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1124 DirstateV2ParseError,
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1125 >,
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1126 > + Send
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1127 + '_,
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1128 > {
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1129 Box::new(filter_map_results(self.iter_nodes(), move |node| {
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1130 Ok(if node.state()?.is_none() {
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1131 Some((
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1132 node.full_path(self.on_disk)?,
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1133 node.cached_directory_mtime()
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1134 .map(|mtime| Timestamp(mtime.seconds())),
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1135 ))
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1136 } else {
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1137 None
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1138 })
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1139 }))
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
1140 }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1141 }