rust/hg-core/src/dirstate_tree/dirstate_map.rs
author Raphaël Gomès <rgomes@octobus.net>
Mon, 09 Jan 2023 19:18:43 +0100
changeset 49930 e98fd81bb151
parent 49924 66ffe3749a48
child 49979 f5b168979626
permissions -rw-r--r--
rust-clippy: fix most warnings in `hg-core` All of these are simple changes that for the most part are clear improvements and the rest are at most equivalent. The remaining warnings have to be fixed either with a bigger refactor like for the nested "revlog" module, or in the dependency `bytes-cast`, which we own. This will be done sometime in the future.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
     1
use bytes_cast::BytesCast;
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
     2
use std::borrow::Cow;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     3
use std::path::PathBuf;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     4
47283
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
     5
use super::on_disk;
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
     6
use super::on_disk::DirstateV2ParseError;
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
     7
use super::owning::OwningDirstateMap;
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
     8
use super::path_with_basename::WithBasename;
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
     9
use crate::dirstate::parsers::pack_entry;
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
    10
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
    11
use crate::dirstate::parsers::parse_dirstate_entries;
48068
bf8837e3d7ce dirstate: Remove the flat Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents: 48061
diff changeset
    12
use crate::dirstate::CopyMapIter;
49101
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
    13
use crate::dirstate::DirstateV2Data;
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
    14
use crate::dirstate::ParentFileData;
48068
bf8837e3d7ce dirstate: Remove the flat Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents: 48061
diff changeset
    15
use crate::dirstate::StateMapIter;
48193
320de901896a dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents: 48192
diff changeset
    16
use crate::dirstate::TruncatedTimestamp;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    17
use crate::matchers::Matcher;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    18
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
    19
use crate::DirstateEntry;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    20
use crate::DirstateError;
49104
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
    21
use crate::DirstateMapError;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    22
use crate::DirstateParents;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    23
use crate::DirstateStatus;
48950
11c0411bf4e2 dirstate-tree: optimize HashMap lookups with raw_entry_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
    24
use crate::FastHashbrownMap as FastHashMap;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    25
use crate::PatternFileWarning;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    26
use crate::StatusError;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    27
use crate::StatusOptions;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    28
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
    29
/// Append to an existing data file if the amount of unreachable data (not used
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
    30
/// anymore) is less than this fraction of the total amount of existing data.
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
    31
const ACCEPTABLE_UNREACHABLE_BYTES_RATIO: f32 = 0.5;
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
    32
49337
6cd249556e20 rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Raphaël Gomès <rgomes@octobus.net>
parents: 49145
diff changeset
    33
#[derive(Debug, PartialEq, Eq)]
6cd249556e20 rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Raphaël Gomès <rgomes@octobus.net>
parents: 49145
diff changeset
    34
/// Version of the on-disk format
6cd249556e20 rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Raphaël Gomès <rgomes@octobus.net>
parents: 49145
diff changeset
    35
pub enum DirstateVersion {
6cd249556e20 rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Raphaël Gomès <rgomes@octobus.net>
parents: 49145
diff changeset
    36
    V1,
6cd249556e20 rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Raphaël Gomès <rgomes@octobus.net>
parents: 49145
diff changeset
    37
    V2,
6cd249556e20 rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Raphaël Gomès <rgomes@octobus.net>
parents: 49145
diff changeset
    38
}
6cd249556e20 rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Raphaël Gomès <rgomes@octobus.net>
parents: 49145
diff changeset
    39
49125
28a6178a07a2 rust: add `Debug` trait to a bunch of structs
Raphaël Gomès <rgomes@octobus.net>
parents: 49124
diff changeset
    40
#[derive(Debug)]
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
    41
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
    42
    /// 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
    43
    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
    44
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
    45
    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
    46
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
    47
    /// 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
    48
    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
    49
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
    50
    /// 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
    51
    /// `.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
    52
    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
    53
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47352
diff changeset
    54
    /// See on_disk::Header
0ef8231e413f dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents: 47352
diff changeset
    55
    pub(super) ignore_patterns_hash: on_disk::IgnorePatternsHash,
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
    56
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
    57
    /// How many bytes of `on_disk` are not used anymore
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
    58
    pub(super) unreachable_bytes: u32,
49145
dd2503a63d33 rust-dirstate-v2: save proper data size if no new data on append
Raphaël Gomès <rgomes@octobus.net>
parents: 49003
diff changeset
    59
dd2503a63d33 rust-dirstate-v2: save proper data size if no new data on append
Raphaël Gomès <rgomes@octobus.net>
parents: 49003
diff changeset
    60
    /// Size of the data used to first load this `DirstateMap`. Used in case
dd2503a63d33 rust-dirstate-v2: save proper data size if no new data on append
Raphaël Gomès <rgomes@octobus.net>
parents: 49003
diff changeset
    61
    /// we need to write some new metadata, but no new data on disk.
dd2503a63d33 rust-dirstate-v2: save proper data size if no new data on append
Raphaël Gomès <rgomes@octobus.net>
parents: 49003
diff changeset
    62
    pub(super) old_data_size: usize,
49337
6cd249556e20 rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Raphaël Gomès <rgomes@octobus.net>
parents: 49145
diff changeset
    63
6cd249556e20 rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Raphaël Gomès <rgomes@octobus.net>
parents: 49145
diff changeset
    64
    pub(super) dirstate_version: DirstateVersion,
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
    65
}
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
    66
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
    67
/// 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
    68
/// 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
    69
/// 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
    70
/// 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
    71
/// 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
    72
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
    73
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
    74
/// 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
    75
/// for on-disk nodes that don’t actually have a `Cow` to borrow.
49125
28a6178a07a2 rust: add `Debug` trait to a bunch of structs
Raphaël Gomès <rgomes@octobus.net>
parents: 49124
diff changeset
    76
#[derive(Debug)]
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
    77
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
    78
    InMemory(&'tree HgPathBuf),
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
    79
    OnDisk(&'on_disk HgPath),
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
49125
28a6178a07a2 rust: add `Debug` trait to a bunch of structs
Raphaël Gomès <rgomes@octobus.net>
parents: 49124
diff changeset
    82
#[derive(Debug)]
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
    83
pub(super) enum ChildNodes<'on_disk> {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
    84
    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
    85
    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
    86
}
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
    87
49125
28a6178a07a2 rust: add `Debug` trait to a bunch of structs
Raphaël Gomès <rgomes@octobus.net>
parents: 49124
diff changeset
    88
#[derive(Debug)]
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
    89
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
    90
    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
    91
    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
    92
}
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
    93
49125
28a6178a07a2 rust: add `Debug` trait to a bunch of structs
Raphaël Gomès <rgomes@octobus.net>
parents: 49124
diff changeset
    94
#[derive(Debug)]
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
    95
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
    96
    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
    97
    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
    98
}
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
    99
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   100
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
   101
    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
   102
        match *self {
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   103
            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
   104
            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
   105
        }
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   106
    }
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   107
}
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   108
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   109
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
   110
    type Target = HgPath;
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   111
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   112
    fn deref(&self) -> &HgPath {
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   113
        match *self {
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   114
            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
   115
            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
   116
        }
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   117
    }
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   118
}
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   119
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   120
impl Default for ChildNodes<'_> {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   121
    fn default() -> Self {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   122
        ChildNodes::InMemory(Default::default())
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   123
    }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   124
}
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   125
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   126
impl<'on_disk> ChildNodes<'on_disk> {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   127
    pub(super) fn as_ref<'tree>(
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   128
        &'tree self,
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   129
    ) -> ChildNodesRef<'tree, 'on_disk> {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   130
        match self {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   131
            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
   132
            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
   133
        }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   134
    }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   135
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   136
    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
   137
        match self {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   138
            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
   139
            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
   140
        }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   141
    }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   142
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   143
    fn make_mut(
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   144
        &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
   145
        on_disk: &'on_disk [u8],
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   146
        unreachable_bytes: &mut u32,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   147
    ) -> Result<
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   148
        &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
   149
        DirstateV2ParseError,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   150
    > {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   151
        match self {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   152
            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
   153
            ChildNodes::OnDisk(nodes) => {
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   154
                *unreachable_bytes +=
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   155
                    std::mem::size_of_val::<[on_disk::Node]>(nodes) as u32;
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   156
                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
   157
                    .iter()
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   158
                    .map(|node| {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   159
                        Ok((
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   160
                            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
   161
                            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
   162
                        ))
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   163
                    })
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   164
                    .collect::<Result<_, _>>()?;
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   165
                *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
   166
                match self {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   167
                    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
   168
                    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
   169
                }
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   170
            }
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   171
        }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   172
    }
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
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
   176
    pub(super) fn get(
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   177
        &self,
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   178
        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
   179
        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
   180
    ) -> 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
   181
        match self {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   182
            ChildNodesRef::InMemory(nodes) => Ok(nodes
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   183
                .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
   184
                .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
   185
            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
   186
                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
   187
                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
   188
                    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
   189
                        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
   190
                        Err(e) => {
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   191
                            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
   192
                            // 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
   193
                            // 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
   194
                            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
   195
                        }
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   196
                    }
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   197
                });
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   198
                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
   199
                    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
   200
                })
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   201
            }
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   202
        }
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
    /// Iterate in undefined order
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   206
    pub(super) fn iter(
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   207
        &self,
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   208
    ) -> 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
   209
        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
   210
            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
   211
                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
   212
            ),
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   213
            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
   214
                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
   215
            }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   216
        }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   217
    }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   218
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   219
    /// Iterate in parallel in undefined order
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   220
    pub(super) fn par_iter(
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   221
        &self,
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   222
    ) -> 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
   223
    {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   224
        use rayon::prelude::*;
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   225
        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
   226
            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
   227
                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
   228
            ),
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   229
            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
   230
                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
   231
            ),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   232
        }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   233
    }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   234
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   235
    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
   236
        match self {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   237
            ChildNodesRef::InMemory(nodes) => {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   238
                let mut vec: Vec<_> = nodes
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   239
                    .iter()
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   240
                    .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
   241
                    .collect();
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   242
                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
   243
                    match node {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   244
                        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
   245
                        NodeRef::OnDisk(_) => unreachable!(),
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   246
                    }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   247
                }
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   248
                // `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
   249
                // 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
   250
                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
   251
                vec
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   252
            }
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   253
            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
   254
                // 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
   255
                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
   256
            }
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   257
        }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   258
    }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   259
}
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   260
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   261
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
   262
    pub(super) fn full_path(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   263
        &self,
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   264
        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
   265
    ) -> Result<&'tree HgPath, DirstateV2ParseError> {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   266
        match self {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   267
            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
   268
            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
   269
        }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   270
    }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   271
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   272
    /// 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
   273
    /// HgPath>` detached from `'tree`
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   274
    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
   275
        &self,
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   276
        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
   277
    ) -> 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
   278
        match self {
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   279
            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
   280
                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
   281
                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
   282
            },
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   283
            NodeRef::OnDisk(node) => {
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47337
diff changeset
   284
                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
   285
            }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   286
        }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   287
    }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   288
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   289
    pub(super) fn base_name(
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<&'tree HgPath, DirstateV2ParseError> {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   293
        match self {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   294
            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
   295
            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
   296
        }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   297
    }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   298
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   299
    pub(super) fn children(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   300
        &self,
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   301
        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
   302
    ) -> 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
   303
        match self {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   304
            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
   305
            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
   306
                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
   307
            }
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   308
        }
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
    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
   312
        match self {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   313
            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
   314
            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
   315
        }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   316
    }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   317
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   318
    pub(super) fn copy_source(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   319
        &self,
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   320
        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
   321
    ) -> Result<Option<&'tree HgPath>, DirstateV2ParseError> {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   322
        match self {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
   323
            NodeRef::InMemory(_path, node) => Ok(node.copy_source.as_deref()),
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   324
            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
   325
        }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   326
    }
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   327
    /// Returns a `BorrowedPath`, which can be turned into a `Cow<'on_disk,
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   328
    /// HgPath>` detached from `'tree`
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   329
    pub(super) fn copy_source_borrowed(
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   330
        &self,
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   331
        on_disk: &'on_disk [u8],
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   332
    ) -> Result<Option<BorrowedPath<'tree, 'on_disk>>, DirstateV2ParseError>
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   333
    {
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   334
        Ok(match self {
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   335
            NodeRef::InMemory(_path, node) => {
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   336
                node.copy_source.as_ref().map(|source| match source {
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   337
                    Cow::Borrowed(on_disk) => BorrowedPath::OnDisk(on_disk),
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   338
                    Cow::Owned(in_memory) => BorrowedPath::InMemory(in_memory),
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   339
                })
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   340
            }
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
   341
            NodeRef::OnDisk(node) => {
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
   342
                node.copy_source(on_disk)?.map(BorrowedPath::OnDisk)
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
   343
            }
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   344
        })
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48421
diff changeset
   345
    }
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   346
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   347
    pub(super) fn entry(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   348
        &self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   349
    ) -> Result<Option<DirstateEntry>, DirstateV2ParseError> {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   350
        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
   351
            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
   352
                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
   353
            }
47337
0654b3b3d2b5 dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents: 47336
diff changeset
   354
            NodeRef::OnDisk(node) => node.entry(),
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   355
        }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   356
    }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   357
47349
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
   358
    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
   359
        &self,
48193
320de901896a dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents: 48192
diff changeset
   360
    ) -> Result<Option<TruncatedTimestamp>, DirstateV2ParseError> {
47349
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
   361
        match self {
48193
320de901896a dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents: 48192
diff changeset
   362
            NodeRef::InMemory(_path, node) => Ok(match node.data {
47349
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
   363
                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
   364
                _ => None,
48193
320de901896a dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents: 48192
diff changeset
   365
            }),
47349
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
   366
            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
   367
        }
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
   368
    }
7138c863d0a1 dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 47348
diff changeset
   369
47478
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
   370
    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
   371
        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
   372
            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
   373
                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
   374
            }
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
   375
            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
   376
        }
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
   377
    }
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
   378
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   379
    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
   380
        match self {
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   381
            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
   382
            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
   383
        }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   384
    }
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   385
}
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   386
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
   387
/// Represents a file or a directory
49125
28a6178a07a2 rust: add `Debug` trait to a bunch of structs
Raphaël Gomès <rgomes@octobus.net>
parents: 49124
diff changeset
   388
#[derive(Default, Debug)]
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
   389
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
   390
    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
   391
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
   392
    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
   393
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
   394
    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
   395
47478
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
   396
    /// 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
   397
    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
   398
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
   399
    /// 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
   400
    /// 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
   401
    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
   402
}
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
   403
49125
28a6178a07a2 rust: add `Debug` trait to a bunch of structs
Raphaël Gomès <rgomes@octobus.net>
parents: 49124
diff changeset
   404
#[derive(Debug)]
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   405
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
   406
    Entry(DirstateEntry),
48193
320de901896a dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents: 48192
diff changeset
   407
    CachedDirectory { mtime: TruncatedTimestamp },
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   408
    None,
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   409
}
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   410
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   411
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
   412
    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
   413
        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
   414
    }
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   415
}
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   416
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   417
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
   418
    fn has_entry(&self) -> bool {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
   419
        matches!(self, NodeData::Entry(_))
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   420
    }
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   421
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   422
    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
   423
        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
   424
            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
   425
            _ => None,
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   426
        }
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   427
    }
49106
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   428
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   429
    fn as_entry_mut(&mut self) -> Option<&mut DirstateEntry> {
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   430
        match self {
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   431
            NodeData::Entry(entry) => Some(entry),
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   432
            _ => None,
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   433
        }
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   434
    }
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   435
}
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   436
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
   437
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
   438
    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
   439
        Self {
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
   440
            on_disk,
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
   441
            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
   442
            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
   443
            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
   444
            ignore_patterns_hash: [0; on_disk::IGNORE_PATTERNS_HASH_LEN],
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   445
            unreachable_bytes: 0,
49145
dd2503a63d33 rust-dirstate-v2: save proper data size if no new data on append
Raphaël Gomès <rgomes@octobus.net>
parents: 49003
diff changeset
   446
            old_data_size: 0,
49337
6cd249556e20 rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Raphaël Gomès <rgomes@octobus.net>
parents: 49145
diff changeset
   447
            dirstate_version: DirstateVersion::V1,
47283
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
   448
        }
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
   449
    }
2a9ddc8094c7 dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents: 47282
diff changeset
   450
49913
c15b415d1bff rust: use `logging_timer` instead of `micro_timer`
Raphaël Gomès <rgomes@octobus.net>
parents: 49373
diff changeset
   451
    #[logging_timer::time("trace")]
47675
48aec076b8fb dirstate-v2: Enforce data size read from the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
   452
    pub fn new_v2(
48aec076b8fb dirstate-v2: Enforce data size read from the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
   453
        on_disk: &'on_disk [u8],
48aec076b8fb dirstate-v2: Enforce data size read from the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
   454
        data_size: usize,
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47681
diff changeset
   455
        metadata: &[u8],
47675
48aec076b8fb dirstate-v2: Enforce data size read from the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
   456
    ) -> Result<Self, DirstateError> {
48aec076b8fb dirstate-v2: Enforce data size read from the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
   457
        if let Some(data) = on_disk.get(..data_size) {
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47681
diff changeset
   458
            Ok(on_disk::read(data, metadata)?)
47675
48aec076b8fb dirstate-v2: Enforce data size read from the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
   459
        } else {
49373
f8ec7b16c98f rust: add message to `DirstateV2ParseError` to give some context
Raphaël Gomès <rgomes@octobus.net>
parents: 49365
diff changeset
   460
            Err(DirstateV2ParseError::new("not enough bytes on disk").into())
47675
48aec076b8fb dirstate-v2: Enforce data size read from the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
   461
        }
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
   462
    }
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
   463
49913
c15b415d1bff rust: use `logging_timer` instead of `micro_timer`
Raphaël Gomès <rgomes@octobus.net>
parents: 49373
diff changeset
   464
    #[logging_timer::time("trace")]
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
   465
    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
   466
        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
   467
    ) -> 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
   468
        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
   469
        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
   470
            return Ok((map, None));
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   471
        }
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
   472
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
   473
        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
   474
            map.on_disk,
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
   475
            |path, entry, copy_source| {
49136
3f5e207f78be rust: use `entry.tracked()` directly
Raphaël Gomès <rgomes@octobus.net>
parents: 49134
diff changeset
   476
                let tracked = entry.tracked();
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   477
                let node = Self::get_or_insert_node_inner(
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
   478
                    map.on_disk,
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   479
                    &mut map.unreachable_bytes,
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
   480
                    &mut map.root,
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
   481
                    path,
47126
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
   482
                    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
   483
                    |ancestor| {
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
   484
                        if tracked {
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
   485
                            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
   486
                        }
47478
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
   487
                        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
   488
                    },
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   489
                )?;
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
   490
                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
   491
                    !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
   492
                    "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
   493
                );
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
   494
                assert!(
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
   495
                    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
   496
                    "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
   497
                );
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
   498
                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
   499
                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
   500
                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
   501
                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
   502
                    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
   503
                }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   504
                Ok(())
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
   505
            },
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
   506
        )?;
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
   507
        let parents = Some(*parents);
47123
d8ac62374943 dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents: 47121
diff changeset
   508
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
   509
        Ok((map, parents))
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   510
    }
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   511
47678
065e61628980 dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47675
diff changeset
   512
    /// Assuming dirstate-v2 format, returns whether the next write should
065e61628980 dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47675
diff changeset
   513
    /// append to the existing data file that contains `self.on_disk` (true),
065e61628980 dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47675
diff changeset
   514
    /// or create a new data file from scratch (false).
065e61628980 dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47675
diff changeset
   515
    pub(super) fn write_should_append(&self) -> bool {
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   516
        let ratio = self.unreachable_bytes as f32 / self.on_disk.len() as f32;
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   517
        ratio < ACCEPTABLE_UNREACHABLE_BYTES_RATIO
47678
065e61628980 dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47675
diff changeset
   518
    }
065e61628980 dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47675
diff changeset
   519
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   520
    fn get_node<'tree>(
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   521
        &'tree self,
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   522
        path: &HgPath,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   523
    ) -> 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
   524
        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
   525
        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
   526
        let mut component =
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
   527
            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
   528
        loop {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
   529
            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
   530
                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
   531
                    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
   532
                    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
   533
                } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   534
                    return Ok(Some(child));
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   535
                }
47099
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
   536
            } else {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   537
                return Ok(None);
47099
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
   538
            }
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
   539
        }
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
   540
    }
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
   541
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
   542
    /// 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
   543
    ///
49133
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   544
    /// `each_ancestor` is a callback that is called for each ancestor node
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   545
    /// when descending the tree. It is used to keep the different counters
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   546
    /// of the `DirstateMap` up-to-date.
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   547
    fn get_node_mut<'tree>(
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   548
        &'tree mut self,
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   549
        path: &HgPath,
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   550
        each_ancestor: impl FnMut(&mut Node),
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   551
    ) -> Result<Option<&'tree mut Node<'on_disk>>, DirstateV2ParseError> {
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   552
        Self::get_node_mut_inner(
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   553
            self.on_disk,
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   554
            &mut self.unreachable_bytes,
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   555
            &mut self.root,
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   556
            path,
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   557
            each_ancestor,
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   558
        )
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   559
    }
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   560
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   561
    /// Lower-level version of `get_node_mut`.
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   562
    ///
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
   563
    /// This takes `root` instead of `&mut self` so that callers can mutate
49131
fcf6f943a142 rust-dirstatemap: add `each_ancestor` argument to `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49130
diff changeset
   564
    /// other fields while the returned borrow is still valid.
fcf6f943a142 rust-dirstatemap: add `each_ancestor` argument to `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49130
diff changeset
   565
    ///
fcf6f943a142 rust-dirstatemap: add `each_ancestor` argument to `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49130
diff changeset
   566
    /// `each_ancestor` is a callback that is called for each ancestor node
fcf6f943a142 rust-dirstatemap: add `each_ancestor` argument to `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49130
diff changeset
   567
    /// when descending the tree. It is used to keep the different counters
fcf6f943a142 rust-dirstatemap: add `each_ancestor` argument to `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49130
diff changeset
   568
    /// of the `DirstateMap` up-to-date.
49133
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   569
    fn get_node_mut_inner<'tree>(
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
   570
        on_disk: &'on_disk [u8],
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   571
        unreachable_bytes: &mut u32,
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
   572
        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
   573
        path: &HgPath,
49131
fcf6f943a142 rust-dirstatemap: add `each_ancestor` argument to `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49130
diff changeset
   574
        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
   575
    ) -> 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
   576
        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
   577
        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
   578
        let mut component =
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
   579
            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
   580
        loop {
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   581
            if let Some(child) = children
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   582
                .make_mut(on_disk, unreachable_bytes)?
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   583
                .get_mut(component)
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
   584
            {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   585
                if let Some(next_component) = components.next() {
49131
fcf6f943a142 rust-dirstatemap: add `each_ancestor` argument to `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49130
diff changeset
   586
                    each_ancestor(child);
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   587
                    component = next_component;
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   588
                    children = &mut child.children;
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   589
                } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   590
                    return Ok(Some(child));
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   591
                }
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
   592
            } else {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   593
                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
   594
            }
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
   595
        }
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
   596
    }
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
   597
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   598
    /// Get a mutable reference to the node at `path`, creating it if it does
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   599
    /// not exist.
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   600
    ///
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   601
    /// `each_ancestor` is a callback that is called for each ancestor node
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   602
    /// when descending the tree. It is used to keep the different counters
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   603
    /// of the `DirstateMap` up-to-date.
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   604
    fn get_or_insert_node<'tree, 'path>(
47474
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
   605
        &'tree mut self,
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   606
        path: &'path HgPath,
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   607
        each_ancestor: impl FnMut(&mut Node),
47474
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
   608
    ) -> Result<&'tree mut Node<'on_disk>, DirstateV2ParseError> {
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   609
        Self::get_or_insert_node_inner(
47474
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
   610
            self.on_disk,
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   611
            &mut self.unreachable_bytes,
47474
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
   612
            &mut self.root,
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
   613
            path,
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
   614
            WithBasename::to_cow_owned,
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   615
            each_ancestor,
47474
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
   616
        )
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
   617
    }
c657beacdf2e dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47409
diff changeset
   618
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   619
    /// Lower-level version of `get_or_insert_node_inner`, which is used when
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   620
    /// parsing disk data to remove allocations for new nodes.
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   621
    fn get_or_insert_node_inner<'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
   622
        on_disk: &'on_disk [u8],
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   623
        unreachable_bytes: &mut u32,
47125
9be618452c3b dirstate-tree: Borrow copy source paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47124
diff changeset
   624
        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
   625
        path: &'path HgPath,
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
   626
        to_cow: impl Fn(
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
   627
            WithBasename<&'path HgPath>,
ecfe0819ada5 dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents: 47125
diff changeset
   628
        ) -> 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
   629
        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
   630
    ) -> 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
   631
        let mut child_nodes = root;
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   632
        let mut inclusive_ancestor_paths =
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   633
            WithBasename::inclusive_ancestors_of(path);
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   634
        let mut ancestor_path = inclusive_ancestor_paths
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   635
            .next()
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   636
            .expect("expected at least one inclusive ancestor");
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   637
        loop {
48950
11c0411bf4e2 dirstate-tree: optimize HashMap lookups with raw_entry_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   638
            let (_, child_node) = child_nodes
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   639
                .make_mut(on_disk, unreachable_bytes)?
48950
11c0411bf4e2 dirstate-tree: optimize HashMap lookups with raw_entry_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   640
                .raw_entry_mut()
11c0411bf4e2 dirstate-tree: optimize HashMap lookups with raw_entry_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   641
                .from_key(ancestor_path.base_name())
11c0411bf4e2 dirstate-tree: optimize HashMap lookups with raw_entry_mut
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
   642
                .or_insert_with(|| (to_cow(ancestor_path), Node::default()));
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   643
            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
   644
                each_ancestor(child_node);
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   645
                ancestor_path = next;
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   646
                child_nodes = &mut child_node.children;
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   647
            } else {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   648
                return Ok(child_node);
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   649
            }
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
   650
        }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   651
    }
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   652
49921
5fff90c7ea9d rust-clippy: reassure `clippy` that 8 arguments is expected
Raphaël Gomès <rgomes@octobus.net>
parents: 49913
diff changeset
   653
    #[allow(clippy::too_many_arguments)]
49101
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   654
    fn reset_state(
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   655
        &mut self,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   656
        filename: &HgPath,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   657
        old_entry_opt: Option<DirstateEntry>,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   658
        wc_tracked: bool,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   659
        p1_tracked: bool,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   660
        p2_info: bool,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   661
        has_meaningful_mtime: bool,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   662
        parent_file_data_opt: Option<ParentFileData>,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   663
    ) -> Result<(), DirstateError> {
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   664
        let (had_entry, was_tracked) = match old_entry_opt {
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   665
            Some(old_entry) => (true, old_entry.tracked()),
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   666
            None => (false, false),
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   667
        };
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   668
        let node = self.get_or_insert_node(filename, |ancestor| {
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   669
            if !had_entry {
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   670
                ancestor.descendants_with_entry_count += 1;
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   671
            }
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   672
            if was_tracked {
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   673
                if !wc_tracked {
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   674
                    ancestor.tracked_descendants_count = ancestor
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   675
                        .tracked_descendants_count
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   676
                        .checked_sub(1)
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   677
                        .expect("tracked count to be >= 0");
49101
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   678
                }
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
   679
            } else if wc_tracked {
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
   680
                ancestor.tracked_descendants_count += 1;
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   681
            }
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   682
        })?;
49101
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   683
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   684
        let v2_data = if let Some(parent_file_data) = parent_file_data_opt {
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   685
            DirstateV2Data {
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   686
                wc_tracked,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   687
                p1_tracked,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   688
                p2_info,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   689
                mode_size: parent_file_data.mode_size,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   690
                mtime: if has_meaningful_mtime {
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   691
                    parent_file_data.mtime
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   692
                } else {
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   693
                    None
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   694
                },
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   695
                ..Default::default()
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   696
            }
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   697
        } else {
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   698
            DirstateV2Data {
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   699
                wc_tracked,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   700
                p1_tracked,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   701
                p2_info,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   702
                ..Default::default()
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   703
            }
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   704
        };
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   705
        node.data = NodeData::Entry(DirstateEntry::from_v2_data(v2_data));
49101
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   706
        if !had_entry {
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   707
            self.nodes_with_entry_count += 1;
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   708
        }
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   709
        Ok(())
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   710
    }
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
   711
49097
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   712
    fn set_tracked(
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   713
        &mut self,
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   714
        filename: &HgPath,
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   715
        old_entry_opt: Option<DirstateEntry>,
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   716
    ) -> Result<bool, DirstateV2ParseError> {
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   717
        let was_tracked = old_entry_opt.map_or(false, |e| e.tracked());
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   718
        let had_entry = old_entry_opt.is_some();
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   719
        let tracked_count_increment = if was_tracked { 0 } else { 1 };
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   720
        let mut new = false;
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   721
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   722
        let node = self.get_or_insert_node(filename, |ancestor| {
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   723
            if !had_entry {
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   724
                ancestor.descendants_with_entry_count += 1;
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   725
            }
49097
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   726
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   727
            ancestor.tracked_descendants_count += tracked_count_increment;
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   728
        })?;
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   729
        if let Some(old_entry) = old_entry_opt {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
   730
            let mut e = old_entry;
49097
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   731
            if e.tracked() {
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   732
                // XXX
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   733
                // This is probably overkill for more case, but we need this to
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   734
                // fully replace the `normallookup` call with `set_tracked`
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   735
                // one. Consider smoothing this in the future.
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   736
                e.set_possibly_dirty();
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   737
            } else {
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   738
                new = true;
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   739
                e.set_tracked();
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   740
            }
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   741
            node.data = NodeData::Entry(e)
49097
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   742
        } else {
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
   743
            node.data = NodeData::Entry(DirstateEntry::new_tracked());
49097
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   744
            self.nodes_with_entry_count += 1;
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   745
            new = true;
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   746
        };
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   747
        Ok(new)
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   748
    }
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   749
49132
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   750
    /// Set a node as untracked in the dirstate.
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   751
    ///
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   752
    /// It is the responsibility of the caller to remove the copy source and/or
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   753
    /// the entry itself if appropriate.
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   754
    ///
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   755
    /// # Panics
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   756
    ///
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   757
    /// Panics if the node does not exist.
49108
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   758
    fn set_untracked(
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   759
        &mut self,
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   760
        filename: &HgPath,
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   761
        old_entry: DirstateEntry,
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   762
    ) -> Result<(), DirstateV2ParseError> {
49133
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   763
        let node = self
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   764
            .get_node_mut(filename, |ancestor| {
49132
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   765
                ancestor.tracked_descendants_count = ancestor
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   766
                    .tracked_descendants_count
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   767
                    .checked_sub(1)
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   768
                    .expect("tracked_descendants_count should be >= 0");
49133
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   769
            })?
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   770
            .expect("node should exist");
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
   771
        let mut new_entry = old_entry;
49108
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   772
        new_entry.set_untracked();
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   773
        node.data = NodeData::Entry(new_entry);
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   774
        Ok(())
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   775
    }
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   776
49132
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   777
    /// Set a node as clean in the dirstate.
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   778
    ///
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   779
    /// It is the responsibility of the caller to remove the copy source.
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   780
    ///
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   781
    /// # Panics
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   782
    ///
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   783
    /// Panics if the node does not exist.
49104
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   784
    fn set_clean(
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   785
        &mut self,
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   786
        filename: &HgPath,
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   787
        old_entry: DirstateEntry,
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   788
        mode: u32,
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   789
        size: u32,
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   790
        mtime: TruncatedTimestamp,
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   791
    ) -> Result<(), DirstateError> {
49133
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   792
        let node = self
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   793
            .get_node_mut(filename, |ancestor| {
49132
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   794
                if !old_entry.tracked() {
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   795
                    ancestor.tracked_descendants_count += 1;
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   796
                }
49133
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   797
            })?
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   798
            .expect("node should exist");
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
   799
        let mut new_entry = old_entry;
49104
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   800
        new_entry.set_clean(mode, size, mtime);
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   801
        node.data = NodeData::Entry(new_entry);
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   802
        Ok(())
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   803
    }
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   804
49132
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   805
    /// Set a node as possibly dirty in the dirstate.
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   806
    ///
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   807
    /// # Panics
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   808
    ///
7276a6007573 rust-dirstatemap: use `get_node_mut` instead or `get_or_insert_node`
Raphaël Gomès <rgomes@octobus.net>
parents: 49131
diff changeset
   809
    /// Panics if the node does not exist.
49106
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   810
    fn set_possibly_dirty(
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   811
        &mut self,
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   812
        filename: &HgPath,
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   813
    ) -> Result<(), DirstateError> {
49133
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   814
        let node = self
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   815
            .get_node_mut(filename, |_ancestor| {})?
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   816
            .expect("node should exist");
49106
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   817
        let entry = node.data.as_entry_mut().expect("entry should exist");
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   818
        entry.set_possibly_dirty();
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   819
        node.data = NodeData::Entry(*entry);
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   820
        Ok(())
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   821
    }
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
   822
49127
f3e8b0b0a8c2 rust-dirstatemap: add `clear_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49126
diff changeset
   823
    /// Clears the cached mtime for the (potential) folder at `path`.
f3e8b0b0a8c2 rust-dirstatemap: add `clear_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49126
diff changeset
   824
    pub(super) fn clear_cached_mtime(
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
   825
        &mut self,
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
   826
        path: &HgPath,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   827
    ) -> Result<(), DirstateV2ParseError> {
49133
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   828
        let node = match self.get_node_mut(path, |_ancestor| {})? {
49127
f3e8b0b0a8c2 rust-dirstatemap: add `clear_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49126
diff changeset
   829
            Some(node) => node,
f3e8b0b0a8c2 rust-dirstatemap: add `clear_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49126
diff changeset
   830
            None => return Ok(()),
f3e8b0b0a8c2 rust-dirstatemap: add `clear_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49126
diff changeset
   831
        };
f3e8b0b0a8c2 rust-dirstatemap: add `clear_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49126
diff changeset
   832
        if let NodeData::CachedDirectory { .. } = &node.data {
f3e8b0b0a8c2 rust-dirstatemap: add `clear_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49126
diff changeset
   833
            node.data = NodeData::None
f3e8b0b0a8c2 rust-dirstatemap: add `clear_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49126
diff changeset
   834
        }
f3e8b0b0a8c2 rust-dirstatemap: add `clear_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49126
diff changeset
   835
        Ok(())
f3e8b0b0a8c2 rust-dirstatemap: add `clear_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49126
diff changeset
   836
    }
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
   837
49128
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   838
    /// Sets the cached mtime for the (potential) folder at `path`.
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   839
    pub(super) fn set_cached_mtime(
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   840
        &mut self,
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   841
        path: &HgPath,
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   842
        mtime: TruncatedTimestamp,
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   843
    ) -> Result<(), DirstateV2ParseError> {
49133
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
   844
        let node = match self.get_node_mut(path, |_ancestor| {})? {
49128
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   845
            Some(node) => node,
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   846
            None => return Ok(()),
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   847
        };
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   848
        match &node.data {
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   849
            NodeData::Entry(_) => {} // Don’t overwrite an entry
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   850
            NodeData::CachedDirectory { .. } | NodeData::None => {
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   851
                node.data = NodeData::CachedDirectory { mtime }
464747faef14 rust-dirstatemap: add `set_cached_mtime` helper method
Raphaël Gomès <rgomes@octobus.net>
parents: 49127
diff changeset
   852
            }
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
   853
        }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   854
        Ok(())
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
   855
    }
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
   856
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   857
    fn iter_nodes<'tree>(
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   858
        &'tree self,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   859
    ) -> impl Iterator<
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   860
        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
   861
    > + 'tree {
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   862
        // Depth first tree traversal.
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   863
        //
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   864
        // 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
   865
        // this would look like:
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   866
        //
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   867
        // ```
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   868
        // fn traverse_children(
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   869
        //     children: &ChildNodes,
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   870
        //     each: &mut impl FnMut(&Node),
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   871
        // ) {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   872
        //     for child in children.values() {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   873
        //         traverse_children(&child.children, each);
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   874
        //         each(child);
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   875
        //     }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   876
        // }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   877
        // ```
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   878
        //
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   879
        // 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
   880
        // call stack. Use an explicit stack instead:
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   881
        let mut stack = Vec::new();
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   882
        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
   883
        std::iter::from_fn(move || {
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
   884
            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
   885
                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
   886
                    Ok(children) => children,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   887
                    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
   888
                };
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   889
                // Pseudo-recursion
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   890
                let new_iter = children.iter();
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   891
                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
   892
                stack.push((child_node, old_iter));
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   893
            }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   894
            // 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
   895
            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
   896
                // "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
   897
                // explicit stack
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   898
                iter = next_iter;
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   899
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   900
                Some(Ok(child_node))
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   901
            } else {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   902
                // 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
   903
                None
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   904
            }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   905
        })
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   906
    }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
   907
49922
b6dc4802e7ef rust: don't use a reference to a `Cow`
Raphaël Gomès <rgomes@octobus.net>
parents: 49921
diff changeset
   908
    fn count_dropped_path(unreachable_bytes: &mut u32, path: Cow<HgPath>) {
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   909
        if let Cow::Borrowed(path) = path {
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   910
            *unreachable_bytes += path.len() as u32
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   911
        }
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
   912
    }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   913
}
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   914
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   915
/// 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
   916
///
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   917
/// 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
   918
/// 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
   919
/// 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
   920
/// `Result`.
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   921
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
   922
    iter: I,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   923
    f: F,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   924
) -> 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
   925
where
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   926
    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
   927
    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
   928
{
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   929
    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
   930
        Ok(node) => f(node).transpose(),
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   931
        Err(e) => Some(Err(e)),
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   932
    })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   933
}
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   934
49924
66ffe3749a48 rust-clippy: simplify return type of debug function
Raphaël Gomès <rgomes@octobus.net>
parents: 49923
diff changeset
   935
type DebugDirstateTuple<'a> = (&'a HgPath, (u8, i32, i32, i32));
66ffe3749a48 rust-clippy: simplify return type of debug function
Raphaël Gomès <rgomes@octobus.net>
parents: 49923
diff changeset
   936
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
   937
impl OwningDirstateMap {
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
   938
    pub fn clear(&mut self) {
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
   939
        self.with_dmap_mut(|map| {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
   940
            map.root = Default::default();
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
   941
            map.nodes_with_entry_count = 0;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
   942
            map.nodes_with_copy_source_count = 0;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
   943
        });
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   944
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   945
49097
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   946
    pub fn set_tracked(
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   947
        &mut self,
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   948
        filename: &HgPath,
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   949
    ) -> Result<bool, DirstateV2ParseError> {
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   950
        let old_entry_opt = self.get(filename)?;
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   951
        self.with_dmap_mut(|map| map.set_tracked(filename, old_entry_opt))
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   952
    }
791430b0b2d2 rust-dirstatemap: add `set_tracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49045
diff changeset
   953
49108
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   954
    pub fn set_untracked(
48047
9b2a51b2c36a dirstate: Propagate dirstate-v2 parse errors from set_dirstate_item
Simon Sapin <simon.sapin@octobus.net>
parents: 48046
diff changeset
   955
        &mut self,
9b2a51b2c36a dirstate: Propagate dirstate-v2 parse errors from set_dirstate_item
Simon Sapin <simon.sapin@octobus.net>
parents: 48046
diff changeset
   956
        filename: &HgPath,
49108
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   957
    ) -> Result<bool, DirstateError> {
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   958
        let old_entry_opt = self.get(filename)?;
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   959
        match old_entry_opt {
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   960
            None => Ok(false),
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   961
            Some(old_entry) => {
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   962
                if !old_entry.tracked() {
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   963
                    // `DirstateMap::set_untracked` is not a noop if
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   964
                    // already not tracked as it will decrement the
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   965
                    // tracked counters while going down.
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   966
                    return Ok(true);
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   967
                }
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   968
                if old_entry.added() {
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   969
                    // Untracking an "added" entry will just result in a
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   970
                    // worthless entry (and other parts of the code will
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   971
                    // complain about it), just drop it entirely.
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   972
                    self.drop_entry_and_copy_source(filename)?;
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   973
                    return Ok(true);
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   974
                }
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   975
                if !old_entry.p2_info() {
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   976
                    self.copy_map_remove(filename)?;
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   977
                }
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   978
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   979
                self.with_dmap_mut(|map| {
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   980
                    map.set_untracked(filename, old_entry)?;
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   981
                    Ok(true)
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   982
                })
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   983
            }
119c7e2b4248 rust-dirstatemap: add `set_untracked` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49106
diff changeset
   984
        }
47692
e5fb14a07866 dirstate-map: move most of `dirstate.update_file` logic in the dsmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47683
diff changeset
   985
    }
e5fb14a07866 dirstate-map: move most of `dirstate.update_file` logic in the dsmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47683
diff changeset
   986
49104
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   987
    pub fn set_clean(
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
   988
        &mut self,
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
   989
        filename: &HgPath,
49104
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   990
        mode: u32,
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   991
        size: u32,
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   992
        mtime: TruncatedTimestamp,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
   993
    ) -> Result<(), DirstateError> {
49104
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   994
        let old_entry = match self.get(filename)? {
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   995
            None => {
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   996
                return Err(
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   997
                    DirstateMapError::PathNotFound(filename.into()).into()
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   998
                )
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
   999
            }
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
  1000
            Some(e) => e,
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
  1001
        };
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
  1002
        self.copy_map_remove(filename)?;
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1003
        self.with_dmap_mut(|map| {
49104
b5c2aca84618 rust-dirstatemap: add `set_clean` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49101
diff changeset
  1004
            map.set_clean(filename, old_entry, mode, size, mtime)
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1005
        })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1006
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1007
49106
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
  1008
    pub fn set_possibly_dirty(
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
  1009
        &mut self,
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
  1010
        filename: &HgPath,
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
  1011
    ) -> Result<(), DirstateError> {
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
  1012
        if self.get(filename)?.is_none() {
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
  1013
            return Err(DirstateMapError::PathNotFound(filename.into()).into());
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
  1014
        }
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
  1015
        self.with_dmap_mut(|map| map.set_possibly_dirty(filename))
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
  1016
    }
c1a3fdedc492 rust-dirstatemap: add `set_possibly_dirty` method
Raphaël Gomès <rgomes@octobus.net>
parents: 49104
diff changeset
  1017
49101
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1018
    pub fn reset_state(
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1019
        &mut self,
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
  1020
        filename: &HgPath,
49101
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1021
        wc_tracked: bool,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1022
        p1_tracked: bool,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1023
        p2_info: bool,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1024
        has_meaningful_mtime: bool,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1025
        parent_file_data_opt: Option<ParentFileData>,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1026
    ) -> Result<(), DirstateError> {
49101
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1027
        if !(p1_tracked || p2_info || wc_tracked) {
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1028
            self.drop_entry_and_copy_source(filename)?;
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1029
            return Ok(());
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1030
        }
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1031
        self.copy_map_remove(filename)?;
47511
eaae39894312 dirstate: move most of the `remove` logic with dirstatemap `removefile`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47478
diff changeset
  1032
        let old_entry_opt = self.get(filename)?;
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1033
        self.with_dmap_mut(|map| {
49101
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1034
            map.reset_state(
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1035
                filename,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1036
                old_entry_opt,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1037
                wc_tracked,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1038
                p1_tracked,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1039
                p2_info,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1040
                has_meaningful_mtime,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1041
                parent_file_data_opt,
dd0430434ce9 rust-dirstatemap: add Rust implementation of `reset_state`
Raphaël Gomès <rgomes@octobus.net>
parents: 49097
diff changeset
  1042
            )
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1043
        })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1044
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1045
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1046
    pub fn drop_entry_and_copy_source(
48050
2ac0e6b23222 dirstate: Replace dropfile with drop_item_and_copy_source
Simon Sapin <simon.sapin@octobus.net>
parents: 48048
diff changeset
  1047
        &mut self,
2ac0e6b23222 dirstate: Replace dropfile with drop_item_and_copy_source
Simon Sapin <simon.sapin@octobus.net>
parents: 48048
diff changeset
  1048
        filename: &HgPath,
2ac0e6b23222 dirstate: Replace dropfile with drop_item_and_copy_source
Simon Sapin <simon.sapin@octobus.net>
parents: 48048
diff changeset
  1049
    ) -> Result<(), DirstateError> {
49123
afe60def963d rust-dirstatemap: use `DirstateEntry::tracked` directly
Raphaël Gomès <rgomes@octobus.net>
parents: 49121
diff changeset
  1050
        let was_tracked = self.get(filename)?.map_or(false, |e| e.tracked());
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
  1051
        struct Dropped {
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
  1052
            was_tracked: bool,
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
  1053
            had_entry: bool,
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
  1054
            had_copy_source: bool,
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
  1055
        }
47352
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
  1056
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
  1057
        /// 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
  1058
        ///
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
  1059
        /// * `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
  1060
        /// * `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
  1061
        ///   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
  1062
        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
  1063
            on_disk: &'on_disk [u8],
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1064
            unreachable_bytes: &mut u32,
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
  1065
            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
  1066
            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
  1067
        ) -> 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
  1068
            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
  1069
                path.split_first_component();
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1070
            let nodes = nodes.make_mut(on_disk, unreachable_bytes)?;
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1071
            let node = if let Some(node) = nodes.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
  1072
            {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1073
                node
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1074
            } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1075
                return Ok(None);
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1076
            };
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
  1077
            let dropped;
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
  1078
            if let Some(rest) = rest_of_path {
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1079
                if let Some((d, removed)) = recur(
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1080
                    on_disk,
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1081
                    unreachable_bytes,
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1082
                    &mut node.children,
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1083
                    rest,
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1084
                )? {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1085
                    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
  1086
                    if dropped.had_entry {
49001
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1087
                        node.descendants_with_entry_count = node
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1088
                            .descendants_with_entry_count
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1089
                            .checked_sub(1)
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1090
                            .expect(
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1091
                                "descendants_with_entry_count should be >= 0",
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1092
                            );
47478
ca8121d26732 dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47477
diff changeset
  1093
                    }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1094
                    if dropped.was_tracked {
49001
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1095
                        node.tracked_descendants_count = node
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1096
                            .tracked_descendants_count
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1097
                            .checked_sub(1)
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1098
                            .expect(
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1099
                                "tracked_descendants_count should be >= 0",
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1100
                            );
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1101
                    }
47352
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
  1102
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
  1103
                    // 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
  1104
                    // child node
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
  1105
                    if removed {
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
  1106
                        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
  1107
                            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
  1108
                        }
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
  1109
                    }
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1110
                } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1111
                    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
  1112
                }
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
  1113
            } else {
49002
fbc02ccc207e rust-dirstatemap: properly decrement counter for tracked descendants
Raphaël Gomès <rgomes@octobus.net>
parents: 49001
diff changeset
  1114
                let entry = node.data.as_entry();
fbc02ccc207e rust-dirstatemap: properly decrement counter for tracked descendants
Raphaël Gomès <rgomes@octobus.net>
parents: 49001
diff changeset
  1115
                let was_tracked = entry.map_or(false, |entry| entry.tracked());
fbc02ccc207e rust-dirstatemap: properly decrement counter for tracked descendants
Raphaël Gomès <rgomes@octobus.net>
parents: 49001
diff changeset
  1116
                let had_entry = entry.is_some();
47348
a4de570e61fa dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
  1117
                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
  1118
                    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
  1119
                }
49003
ce919b1a1063 rust-dirstatemap: correctly decrement the copies counter
Raphaël Gomès <rgomes@octobus.net>
parents: 49002
diff changeset
  1120
                let mut had_copy_source = false;
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1121
                if let Some(source) = &node.copy_source {
49922
b6dc4802e7ef rust: don't use a reference to a `Cow`
Raphaël Gomès <rgomes@octobus.net>
parents: 49921
diff changeset
  1122
                    DirstateMap::count_dropped_path(
b6dc4802e7ef rust: don't use a reference to a `Cow`
Raphaël Gomès <rgomes@octobus.net>
parents: 49921
diff changeset
  1123
                        unreachable_bytes,
b6dc4802e7ef rust: don't use a reference to a `Cow`
Raphaël Gomès <rgomes@octobus.net>
parents: 49921
diff changeset
  1124
                        Cow::Borrowed(source),
b6dc4802e7ef rust: don't use a reference to a `Cow`
Raphaël Gomès <rgomes@octobus.net>
parents: 49921
diff changeset
  1125
                    );
49003
ce919b1a1063 rust-dirstatemap: correctly decrement the copies counter
Raphaël Gomès <rgomes@octobus.net>
parents: 49002
diff changeset
  1126
                    had_copy_source = true;
48050
2ac0e6b23222 dirstate: Replace dropfile with drop_item_and_copy_source
Simon Sapin <simon.sapin@octobus.net>
parents: 48048
diff changeset
  1127
                    node.copy_source = None
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1128
                }
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
  1129
                dropped = Dropped {
49002
fbc02ccc207e rust-dirstatemap: properly decrement counter for tracked descendants
Raphaël Gomès <rgomes@octobus.net>
parents: 49001
diff changeset
  1130
                    was_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
  1131
                    had_entry,
49003
ce919b1a1063 rust-dirstatemap: correctly decrement the copies counter
Raphaël Gomès <rgomes@octobus.net>
parents: 49002
diff changeset
  1132
                    had_copy_source,
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
  1133
                };
47193
47ccab19bf9f dirstate-tree: Remove newly-empty nodes after removing a `DirstateEntry`
Simon Sapin <simon.sapin@octobus.net>
parents: 47192
diff changeset
  1134
            }
47ccab19bf9f dirstate-tree: Remove newly-empty nodes after removing a `DirstateEntry`
Simon Sapin <simon.sapin@octobus.net>
parents: 47192
diff changeset
  1135
            // 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
  1136
            // 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
  1137
            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
  1138
                && 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
  1139
                && 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
  1140
            if remove {
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1141
                let (key, _) =
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1142
                    nodes.remove_entry(first_path_component).unwrap();
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1143
                DirstateMap::count_dropped_path(
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1144
                    unreachable_bytes,
49922
b6dc4802e7ef rust: don't use a reference to a `Cow`
Raphaël Gomès <rgomes@octobus.net>
parents: 49921
diff changeset
  1145
                    Cow::Borrowed(key.full_path()),
47681
d94118365ec5 dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47678
diff changeset
  1146
                )
47192
1249eb9cc332 dirstate-tree: Refactor DirstateMap::drop_file to be recursive
Simon Sapin <simon.sapin@octobus.net>
parents: 47126
diff changeset
  1147
            }
47352
9d58e54b5966 dirstate-v2: Drop parent directory cache when removing a dirstate node
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
  1148
            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
  1149
        }
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
  1150
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1151
        self.with_dmap_mut(|map| {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1152
            if let Some((dropped, _removed)) = recur(
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1153
                map.on_disk,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1154
                &mut map.unreachable_bytes,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1155
                &mut map.root,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1156
                filename,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1157
            )? {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1158
                if dropped.had_entry {
49001
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1159
                    map.nodes_with_entry_count = map
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1160
                        .nodes_with_entry_count
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1161
                        .checked_sub(1)
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1162
                        .expect("nodes_with_entry_count should be >= 0");
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1163
                }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1164
                if dropped.had_copy_source {
49001
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1165
                    map.nodes_with_copy_source_count = map
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1166
                        .nodes_with_copy_source_count
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1167
                        .checked_sub(1)
2593873cda0f rust-dirstate: panic if the DirstateMap counters go below 0
Raphaël Gomès <rgomes@octobus.net>
parents: 49000
diff changeset
  1168
                        .expect("nodes_with_copy_source_count should be >= 0");
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1169
                }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1170
            } else {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1171
                debug_assert!(!was_tracked);
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
  1172
            }
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1173
            Ok(())
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1174
        })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1175
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1176
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1177
    pub fn has_tracked_dir(
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1178
        &mut self,
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
  1179
        directory: &HgPath,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1180
    ) -> Result<bool, DirstateError> {
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1181
        self.with_dmap_mut(|map| {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1182
            if let Some(node) = map.get_node(directory)? {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1183
                // A node without a `DirstateEntry` was created to hold child
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1184
                // nodes, and is therefore a directory.
49140
748ac6400eaa rust-dirstatemap: stop using `state()` in the cache logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49136
diff changeset
  1185
                let is_dir = node.entry()?.is_none();
748ac6400eaa rust-dirstatemap: stop using `state()` in the cache logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49136
diff changeset
  1186
                Ok(is_dir && node.tracked_descendants_count() > 0)
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1187
            } else {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1188
                Ok(false)
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1189
            }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1190
        })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1191
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1192
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1193
    pub fn has_dir(
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1194
        &mut self,
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1195
        directory: &HgPath,
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1196
    ) -> Result<bool, DirstateError> {
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1197
        self.with_dmap_mut(|map| {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1198
            if let Some(node) = map.get_node(directory)? {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1199
                // A node without a `DirstateEntry` was created to hold child
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1200
                // nodes, and is therefore a directory.
49140
748ac6400eaa rust-dirstatemap: stop using `state()` in the cache logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49136
diff changeset
  1201
                let is_dir = node.entry()?.is_none();
748ac6400eaa rust-dirstatemap: stop using `state()` in the cache logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49136
diff changeset
  1202
                Ok(is_dir && node.descendants_with_entry_count() > 0)
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1203
            } else {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1204
                Ok(false)
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1205
            }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1206
        })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1207
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1208
49913
c15b415d1bff rust: use `logging_timer` instead of `micro_timer`
Raphaël Gomès <rgomes@octobus.net>
parents: 49373
diff changeset
  1209
    #[logging_timer::time("trace")]
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1210
    pub fn pack_v1(
48416
c1b633db67fc rust: Serializing a DirstateMap does not mutate it anymore
Simon Sapin <simon.sapin@octobus.net>
parents: 48392
diff changeset
  1211
        &self,
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1212
        parents: DirstateParents,
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1213
    ) -> Result<Vec<u8>, DirstateError> {
48416
c1b633db67fc rust: Serializing a DirstateMap does not mutate it anymore
Simon Sapin <simon.sapin@octobus.net>
parents: 48392
diff changeset
  1214
        let map = self.get_map();
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1215
        // 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
  1216
        // reallocations
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1217
        let mut size = parents.as_bytes().len();
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1218
        for node in map.iter_nodes() {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1219
            let node = node?;
48392
434de12918fd dirstate: remove need_delay logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48260
diff changeset
  1220
            if node.entry()?.is_some() {
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
  1221
                size += packed_entry_size(
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1222
                    node.full_path(map.on_disk)?,
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1223
                    node.copy_source(map.on_disk)?,
47336
8d0260d0dbc9 dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
  1224
                );
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1225
            }
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1226
        }
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1227
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1228
        let mut packed = Vec::with_capacity(size);
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1229
        packed.extend(parents.as_bytes());
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1230
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1231
        for node in map.iter_nodes() {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1232
            let node = node?;
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1233
            if let Some(entry) = node.entry()? {
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1234
                pack_entry(
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1235
                    node.full_path(map.on_disk)?,
47333
69530e5d4fe5 dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents: 47332
diff changeset
  1236
                    &entry,
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1237
                    node.copy_source(map.on_disk)?,
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1238
                    &mut packed,
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1239
                );
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1240
            }
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1241
        }
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
  1242
        Ok(packed)
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1243
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1244
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47681
diff changeset
  1245
    /// Returns new data and metadata together with whether that data should be
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47681
diff changeset
  1246
    /// appended to the existing data file whose content is at
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1247
    /// `map.on_disk` (true), instead of written to a new data file
49145
dd2503a63d33 rust-dirstate-v2: save proper data size if no new data on append
Raphaël Gomès <rgomes@octobus.net>
parents: 49003
diff changeset
  1248
    /// (false), and the previous size of data on disk.
49913
c15b415d1bff rust: use `logging_timer` instead of `micro_timer`
Raphaël Gomès <rgomes@octobus.net>
parents: 49373
diff changeset
  1249
    #[logging_timer::time("trace")]
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1250
    pub fn pack_v2(
48416
c1b633db67fc rust: Serializing a DirstateMap does not mutate it anymore
Simon Sapin <simon.sapin@octobus.net>
parents: 48392
diff changeset
  1251
        &self,
47678
065e61628980 dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents: 47675
diff changeset
  1252
        can_append: bool,
49145
dd2503a63d33 rust-dirstate-v2: save proper data size if no new data on append
Raphaël Gomès <rgomes@octobus.net>
parents: 49003
diff changeset
  1253
    ) -> Result<(Vec<u8>, on_disk::TreeMetadata, bool, usize), DirstateError>
dd2503a63d33 rust-dirstate-v2: save proper data size if no new data on append
Raphaël Gomès <rgomes@octobus.net>
parents: 49003
diff changeset
  1254
    {
48416
c1b633db67fc rust: Serializing a DirstateMap does not mutate it anymore
Simon Sapin <simon.sapin@octobus.net>
parents: 48392
diff changeset
  1255
        let map = self.get_map();
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1256
        on_disk::write(map, can_append)
47280
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
  1257
    }
1766130fe9ba dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 47193
diff changeset
  1258
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1259
    /// `callback` allows the caller to process and do something with the
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1260
    /// results of the status. This is needed to do so efficiently (i.e.
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1261
    /// without cloning the `DirstateStatus` object with its paths) because
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1262
    /// we need to borrow from `Self`.
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1263
    pub fn with_status<R>(
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1264
        &mut self,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1265
        matcher: &(dyn Matcher + Sync),
47112
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
  1266
        root_dir: PathBuf,
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
  1267
        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
  1268
        options: StatusOptions,
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1269
        callback: impl for<'r> FnOnce(
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1270
            Result<(DirstateStatus<'r>, Vec<PatternFileWarning>), StatusError>,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1271
        ) -> R,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1272
    ) -> R {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1273
        self.with_dmap_mut(|map| {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1274
            callback(super::status::status(
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1275
                map,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1276
                matcher,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1277
                root_dir,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1278
                ignore_files,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1279
                options,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1280
            ))
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1281
        })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1282
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1283
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1284
    pub fn copy_map_len(&self) -> usize {
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1285
        let map = self.get_map();
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1286
        map.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
  1287
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1288
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1289
    pub fn copy_map_iter(&self) -> CopyMapIter<'_> {
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1290
        let map = self.get_map();
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1291
        Box::new(filter_map_results(map.iter_nodes(), move |node| {
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1292
            Ok(if let Some(source) = node.copy_source(map.on_disk)? {
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1293
                Some((node.full_path(map.on_disk)?, source))
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1294
            } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1295
                None
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1296
            })
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
  1297
        }))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1298
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1299
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1300
    pub fn copy_map_contains_key(
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1301
        &self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1302
        key: &HgPath,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1303
    ) -> Result<bool, DirstateV2ParseError> {
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1304
        let map = self.get_map();
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1305
        Ok(if let Some(node) = map.get_node(key)? {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1306
            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
  1307
        } else {
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
  1308
            false
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1309
        })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1310
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1311
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1312
    pub fn copy_map_get(
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1313
        &self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1314
        key: &HgPath,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1315
    ) -> Result<Option<&HgPath>, DirstateV2ParseError> {
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1316
        let map = self.get_map();
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1317
        if let Some(node) = map.get_node(key)? {
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1318
            if let Some(source) = node.copy_source(map.on_disk)? {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1319
                return Ok(Some(source));
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1320
            }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1321
        }
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1322
        Ok(None)
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1323
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1324
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1325
    pub fn copy_map_remove(
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1326
        &mut self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1327
        key: &HgPath,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1328
    ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> {
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1329
        self.with_dmap_mut(|map| {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1330
            let count = &mut map.nodes_with_copy_source_count;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1331
            let unreachable_bytes = &mut map.unreachable_bytes;
49133
23a5659125c8 rust-dirstatemap: add simpler version of `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49132
diff changeset
  1332
            Ok(DirstateMap::get_node_mut_inner(
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1333
                map.on_disk,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1334
                unreachable_bytes,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1335
                &mut map.root,
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1336
                key,
49131
fcf6f943a142 rust-dirstatemap: add `each_ancestor` argument to `get_node_mut`
Raphaël Gomès <rgomes@octobus.net>
parents: 49130
diff changeset
  1337
                |_ancestor| {},
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1338
            )?
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1339
            .and_then(|node| {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1340
                if let Some(source) = &node.copy_source {
49134
8c59d8adcf5b rust-dirstatemap: use a checked sub instead of a potentially underflowing one
Raphaël Gomès <rgomes@octobus.net>
parents: 49133
diff changeset
  1341
                    *count = count
8c59d8adcf5b rust-dirstatemap: use a checked sub instead of a potentially underflowing one
Raphaël Gomès <rgomes@octobus.net>
parents: 49133
diff changeset
  1342
                        .checked_sub(1)
8c59d8adcf5b rust-dirstatemap: use a checked sub instead of a potentially underflowing one
Raphaël Gomès <rgomes@octobus.net>
parents: 49133
diff changeset
  1343
                        .expect("nodes_with_copy_source_count should be >= 0");
49922
b6dc4802e7ef rust: don't use a reference to a `Cow`
Raphaël Gomès <rgomes@octobus.net>
parents: 49921
diff changeset
  1344
                    DirstateMap::count_dropped_path(
b6dc4802e7ef rust: don't use a reference to a `Cow`
Raphaël Gomès <rgomes@octobus.net>
parents: 49921
diff changeset
  1345
                        unreachable_bytes,
b6dc4802e7ef rust: don't use a reference to a `Cow`
Raphaël Gomès <rgomes@octobus.net>
parents: 49921
diff changeset
  1346
                        Cow::Borrowed(source),
b6dc4802e7ef rust: don't use a reference to a `Cow`
Raphaël Gomès <rgomes@octobus.net>
parents: 49921
diff changeset
  1347
                    );
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1348
                }
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1349
                node.copy_source.take().map(Cow::into_owned)
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1350
            }))
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1351
        })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1352
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1353
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1354
    pub fn copy_map_insert(
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1355
        &mut self,
49124
d9a66d62c604 rust-dirstatemap: use `&HgPath` instead of `HgPathBuf` in `copy_map_insert`
Raphaël Gomès <rgomes@octobus.net>
parents: 49123
diff changeset
  1356
        key: &HgPath,
d9a66d62c604 rust-dirstatemap: use `&HgPath` instead of `HgPathBuf` in `copy_map_insert`
Raphaël Gomès <rgomes@octobus.net>
parents: 49123
diff changeset
  1357
        value: &HgPath,
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1358
    ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> {
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1359
        self.with_dmap_mut(|map| {
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
  1360
            let node = map.get_or_insert_node(key, |_ancestor| {})?;
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
  1361
            let had_copy_source = node.copy_source.is_none();
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
  1362
            let old = node
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
  1363
                .copy_source
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
  1364
                .replace(value.to_owned().into())
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
  1365
                .map(Cow::into_owned);
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
  1366
            if had_copy_source {
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1367
                map.nodes_with_copy_source_count += 1
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1368
            }
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
  1369
            Ok(old)
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1370
        })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1371
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1372
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1373
    pub fn len(&self) -> usize {
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1374
        let map = self.get_map();
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1375
        map.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
  1376
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1377
49923
547d6817e0c3 rust-clippy: add `is_empty` method to please the `clippy` gods
Raphaël Gomès <rgomes@octobus.net>
parents: 49922
diff changeset
  1378
    pub fn is_empty(&self) -> bool {
547d6817e0c3 rust-clippy: add `is_empty` method to please the `clippy` gods
Raphaël Gomès <rgomes@octobus.net>
parents: 49922
diff changeset
  1379
        self.len() == 0
547d6817e0c3 rust-clippy: add `is_empty` method to please the `clippy` gods
Raphaël Gomès <rgomes@octobus.net>
parents: 49922
diff changeset
  1380
    }
547d6817e0c3 rust-clippy: add `is_empty` method to please the `clippy` gods
Raphaël Gomès <rgomes@octobus.net>
parents: 49922
diff changeset
  1381
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1382
    pub fn contains_key(
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1383
        &self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1384
        key: &HgPath,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1385
    ) -> Result<bool, DirstateV2ParseError> {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1386
        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
  1387
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1388
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1389
    pub fn get(
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1390
        &self,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1391
        key: &HgPath,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1392
    ) -> Result<Option<DirstateEntry>, DirstateV2ParseError> {
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1393
        let map = self.get_map();
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1394
        Ok(if let Some(node) = map.get_node(key)? {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1395
            node.entry()?
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1396
        } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1397
            None
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1398
        })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1399
    }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1400
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1401
    pub fn iter(&self) -> StateMapIter<'_> {
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1402
        let map = self.get_map();
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1403
        Box::new(filter_map_results(map.iter_nodes(), move |node| {
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1404
            Ok(if let Some(entry) = node.entry()? {
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1405
                Some((node.full_path(map.on_disk)?, entry))
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1406
            } else {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1407
                None
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47334
diff changeset
  1408
            })
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
  1409
        }))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1410
    }
47351
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
  1411
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1412
    pub fn iter_tracked_dirs(
47683
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1413
        &mut self,
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1414
    ) -> Result<
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1415
        Box<
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1416
            dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>>
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1417
                + Send
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1418
                + '_,
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1419
        >,
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1420
        DirstateError,
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1421
    > {
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents: 48454
diff changeset
  1422
        let map = self.get_map();
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1423
        let on_disk = map.on_disk;
47683
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1424
        Ok(Box::new(filter_map_results(
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1425
            map.iter_nodes(),
47683
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1426
            move |node| {
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1427
                Ok(if node.tracked_descendants_count() > 0 {
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1428
                    Some(node.full_path(on_disk)?)
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1429
                } else {
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1430
                    None
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1431
                })
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1432
            },
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1433
        )))
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1434
    }
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1435
49120
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1436
    /// Only public because it needs to be exposed to the Python layer.
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1437
    /// It is not the full `setparents` logic, only the parts that mutate the
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1438
    /// entries.
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1439
    pub fn setparents_fixup(
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1440
        &mut self,
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1441
    ) -> Result<Vec<(HgPathBuf, HgPathBuf)>, DirstateV2ParseError> {
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1442
        // XXX
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1443
        // All the copying and re-querying is quite inefficient, but this is
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1444
        // still a lot better than doing it from Python.
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1445
        //
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1446
        // The better solution is to develop a mechanism for `iter_mut`,
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1447
        // which will be a lot more involved: we're dealing with a lazy,
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1448
        // append-mostly, tree-like data structure. This will do for now.
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1449
        let mut copies = vec![];
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1450
        let mut files_with_p2_info = vec![];
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1451
        for res in self.iter() {
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1452
            let (path, entry) = res?;
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1453
            if entry.p2_info() {
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1454
                files_with_p2_info.push(path.to_owned())
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1455
            }
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1456
        }
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1457
        self.with_dmap_mut(|map| {
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1458
            for path in files_with_p2_info.iter() {
49130
3926bfef28e4 rust-dirstatemap: add simpler method `get_or_insert_node` for the common case
Raphaël Gomès <rgomes@octobus.net>
parents: 49129
diff changeset
  1459
                let node = map.get_or_insert_node(path, |_| {})?;
49120
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1460
                let entry =
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1461
                    node.data.as_entry_mut().expect("entry should exist");
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1462
                entry.drop_merge_data();
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1463
                if let Some(source) = node.copy_source.take().as_deref() {
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1464
                    copies.push((path.to_owned(), source.to_owned()));
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1465
                }
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1466
            }
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1467
            Ok(copies)
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1468
        })
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1469
    }
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49112
diff changeset
  1470
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1471
    pub fn debug_iter(
47351
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
  1472
        &self,
48023
357307feaf61 debugstate: Always call dirstatemap.debug_iter()
Simon Sapin <simon.sapin@octobus.net>
parents: 48022
diff changeset
  1473
        all: bool,
47351
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
  1474
    ) -> Box<
49924
66ffe3749a48 rust-clippy: simplify return type of debug function
Raphaël Gomès <rgomes@octobus.net>
parents: 49923
diff changeset
  1475
        dyn Iterator<Item = Result<DebugDirstateTuple, DirstateV2ParseError>>
66ffe3749a48 rust-clippy: simplify return type of debug function
Raphaël Gomès <rgomes@octobus.net>
parents: 49923
diff changeset
  1476
            + Send
47351
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
  1477
            + '_,
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
  1478
    > {
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1479
        let map = self.get_map();
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1480
        Box::new(filter_map_results(map.iter_nodes(), move |node| {
47683
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1481
            let debug_tuple = if let Some(entry) = node.entry()? {
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1482
                entry.debug_tuple()
48023
357307feaf61 debugstate: Always call dirstatemap.debug_iter()
Simon Sapin <simon.sapin@octobus.net>
parents: 48022
diff changeset
  1483
            } else if !all {
357307feaf61 debugstate: Always call dirstatemap.debug_iter()
Simon Sapin <simon.sapin@octobus.net>
parents: 48022
diff changeset
  1484
                return Ok(None);
48193
320de901896a dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents: 48192
diff changeset
  1485
            } else if let Some(mtime) = node.cached_directory_mtime()? {
320de901896a dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents: 48192
diff changeset
  1486
                (b' ', 0, -1, mtime.truncated_seconds() as i32)
47351
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
  1487
            } else {
47683
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1488
                (b' ', 0, -1, -1)
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
  1489
            };
48069
3d0a9c6e614d dirstate: Remove the Rust abstraction DirstateMapMethods
Simon Sapin <simon.sapin@octobus.net>
parents: 48068
diff changeset
  1490
            Ok(Some((node.full_path(map.on_disk)?, debug_tuple)))
47351
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
  1491
        }))
3b9914b28133 dirstate-v2: Add --dirs to debugdirstate command
Simon Sapin <simon.sapin@octobus.net>
parents: 47349
diff changeset
  1492
    }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
  1493
}
49126
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1494
#[cfg(test)]
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1495
mod tests {
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1496
    use super::*;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1497
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1498
    /// Shortcut to return tracked descendants of a path.
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1499
    /// Panics if the path does not exist.
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1500
    fn tracked_descendants(map: &OwningDirstateMap, path: &[u8]) -> u32 {
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1501
        let path = dbg!(HgPath::new(path));
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1502
        let node = map.get_map().get_node(path);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1503
        node.unwrap().unwrap().tracked_descendants_count()
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1504
    }
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1505
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1506
    /// Shortcut to return descendants with an entry.
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1507
    /// Panics if the path does not exist.
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1508
    fn descendants_with_an_entry(map: &OwningDirstateMap, path: &[u8]) -> u32 {
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1509
        let path = dbg!(HgPath::new(path));
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1510
        let node = map.get_map().get_node(path);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1511
        node.unwrap().unwrap().descendants_with_entry_count()
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1512
    }
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1513
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1514
    fn assert_does_not_exist(map: &OwningDirstateMap, path: &[u8]) {
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1515
        let path = dbg!(HgPath::new(path));
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1516
        let node = map.get_map().get_node(path);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1517
        assert!(node.unwrap().is_none());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1518
    }
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1519
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1520
    /// Shortcut for path creation in tests
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1521
    fn p(b: &[u8]) -> &HgPath {
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1522
        HgPath::new(b)
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1523
    }
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1524
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1525
    /// Test the very simple case a single tracked file
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1526
    #[test]
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1527
    fn test_tracked_descendants_simple() -> Result<(), DirstateError> {
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1528
        let mut map = OwningDirstateMap::new_empty(vec![]);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1529
        assert_eq!(map.len(), 0);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1530
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1531
        map.set_tracked(p(b"some/nested/path"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1532
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1533
        assert_eq!(map.len(), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1534
        assert_eq!(tracked_descendants(&map, b"some"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1535
        assert_eq!(tracked_descendants(&map, b"some/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1536
        assert_eq!(tracked_descendants(&map, b"some/nested/path"), 0);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1537
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1538
        map.set_untracked(p(b"some/nested/path"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1539
        assert_eq!(map.len(), 0);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1540
        assert!(map.get_map().get_node(p(b"some"))?.is_none());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1541
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1542
        Ok(())
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1543
    }
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1544
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1545
    /// Test the simple case of all tracked, but multiple files
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1546
    #[test]
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1547
    fn test_tracked_descendants_multiple() -> Result<(), DirstateError> {
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1548
        let mut map = OwningDirstateMap::new_empty(vec![]);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1549
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1550
        map.set_tracked(p(b"some/nested/path"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1551
        map.set_tracked(p(b"some/nested/file"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1552
        // one layer without any files to test deletion cascade
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1553
        map.set_tracked(p(b"some/other/nested/path"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1554
        map.set_tracked(p(b"root_file"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1555
        map.set_tracked(p(b"some/file"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1556
        map.set_tracked(p(b"some/file2"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1557
        map.set_tracked(p(b"some/file3"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1558
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1559
        assert_eq!(map.len(), 7);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1560
        assert_eq!(tracked_descendants(&map, b"some"), 6);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1561
        assert_eq!(tracked_descendants(&map, b"some/nested"), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1562
        assert_eq!(tracked_descendants(&map, b"some/other"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1563
        assert_eq!(tracked_descendants(&map, b"some/other/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1564
        assert_eq!(tracked_descendants(&map, b"some/nested/path"), 0);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1565
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1566
        map.set_untracked(p(b"some/nested/path"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1567
        assert_eq!(map.len(), 6);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1568
        assert_eq!(tracked_descendants(&map, b"some"), 5);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1569
        assert_eq!(tracked_descendants(&map, b"some/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1570
        assert_eq!(tracked_descendants(&map, b"some/other"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1571
        assert_eq!(tracked_descendants(&map, b"some/other/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1572
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1573
        map.set_untracked(p(b"some/nested/file"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1574
        assert_eq!(map.len(), 5);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1575
        assert_eq!(tracked_descendants(&map, b"some"), 4);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1576
        assert_eq!(tracked_descendants(&map, b"some/other"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1577
        assert_eq!(tracked_descendants(&map, b"some/other/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1578
        assert_does_not_exist(&map, b"some_nested");
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1579
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1580
        map.set_untracked(p(b"some/other/nested/path"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1581
        assert_eq!(map.len(), 4);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1582
        assert_eq!(tracked_descendants(&map, b"some"), 3);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1583
        assert_does_not_exist(&map, b"some/other");
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1584
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1585
        map.set_untracked(p(b"root_file"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1586
        assert_eq!(map.len(), 3);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1587
        assert_eq!(tracked_descendants(&map, b"some"), 3);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1588
        assert_does_not_exist(&map, b"root_file");
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1589
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1590
        map.set_untracked(p(b"some/file"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1591
        assert_eq!(map.len(), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1592
        assert_eq!(tracked_descendants(&map, b"some"), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1593
        assert_does_not_exist(&map, b"some/file");
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1594
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1595
        map.set_untracked(p(b"some/file2"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1596
        assert_eq!(map.len(), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1597
        assert_eq!(tracked_descendants(&map, b"some"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1598
        assert_does_not_exist(&map, b"some/file2");
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1599
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1600
        map.set_untracked(p(b"some/file3"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1601
        assert_eq!(map.len(), 0);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1602
        assert_does_not_exist(&map, b"some/file3");
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1603
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1604
        Ok(())
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1605
    }
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1606
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1607
    /// Check with a mix of tracked and non-tracked items
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1608
    #[test]
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1609
    fn test_tracked_descendants_different() -> Result<(), DirstateError> {
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1610
        let mut map = OwningDirstateMap::new_empty(vec![]);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1611
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1612
        // A file that was just added
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1613
        map.set_tracked(p(b"some/nested/path"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1614
        // This has no information, the dirstate should ignore it
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1615
        map.reset_state(p(b"some/file"), false, false, false, false, None)?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1616
        assert_does_not_exist(&map, b"some/file");
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1617
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1618
        // A file that was removed
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1619
        map.reset_state(
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1620
            p(b"some/nested/file"),
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1621
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1622
            true,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1623
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1624
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1625
            None,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1626
        )?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1627
        assert!(!map.get(p(b"some/nested/file"))?.unwrap().tracked());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1628
        // Only present in p2
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1629
        map.reset_state(p(b"some/file3"), false, false, true, false, None)?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1630
        assert!(!map.get(p(b"some/file3"))?.unwrap().tracked());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1631
        // A file that was merged
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1632
        map.reset_state(p(b"root_file"), true, true, true, false, None)?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1633
        assert!(map.get(p(b"root_file"))?.unwrap().tracked());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1634
        // A file that is added, with info from p2
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1635
        // XXX is that actually possible?
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1636
        map.reset_state(p(b"some/file2"), true, false, true, false, None)?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1637
        assert!(map.get(p(b"some/file2"))?.unwrap().tracked());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1638
        // A clean file
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1639
        // One layer without any files to test deletion cascade
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1640
        map.reset_state(
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1641
            p(b"some/other/nested/path"),
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1642
            true,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1643
            true,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1644
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1645
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1646
            None,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1647
        )?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1648
        assert!(map.get(p(b"some/other/nested/path"))?.unwrap().tracked());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1649
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1650
        assert_eq!(map.len(), 6);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1651
        assert_eq!(tracked_descendants(&map, b"some"), 3);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1652
        assert_eq!(descendants_with_an_entry(&map, b"some"), 5);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1653
        assert_eq!(tracked_descendants(&map, b"some/other/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1654
        assert_eq!(descendants_with_an_entry(&map, b"some/other/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1655
        assert_eq!(tracked_descendants(&map, b"some/other/nested/path"), 0);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1656
        assert_eq!(
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1657
            descendants_with_an_entry(&map, b"some/other/nested/path"),
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1658
            0
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1659
        );
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1660
        assert_eq!(tracked_descendants(&map, b"some/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1661
        assert_eq!(descendants_with_an_entry(&map, b"some/nested"), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1662
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1663
        // might as well check this
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1664
        map.set_untracked(p(b"path/does/not/exist"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1665
        assert_eq!(map.len(), 6);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1666
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1667
        map.set_untracked(p(b"some/other/nested/path"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1668
        // It is set untracked but not deleted since it held other information
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1669
        assert_eq!(map.len(), 6);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1670
        assert_eq!(tracked_descendants(&map, b"some"), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1671
        assert_eq!(descendants_with_an_entry(&map, b"some"), 5);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1672
        assert_eq!(descendants_with_an_entry(&map, b"some/other"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1673
        assert_eq!(descendants_with_an_entry(&map, b"some/other/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1674
        assert_eq!(tracked_descendants(&map, b"some/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1675
        assert_eq!(descendants_with_an_entry(&map, b"some/nested"), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1676
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1677
        map.set_untracked(p(b"some/nested/path"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1678
        // It is set untracked *and* deleted since it was only added
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1679
        assert_eq!(map.len(), 5);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1680
        assert_eq!(tracked_descendants(&map, b"some"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1681
        assert_eq!(descendants_with_an_entry(&map, b"some"), 4);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1682
        assert_eq!(tracked_descendants(&map, b"some/nested"), 0);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1683
        assert_eq!(descendants_with_an_entry(&map, b"some/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1684
        assert_does_not_exist(&map, b"some/nested/path");
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1685
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1686
        map.set_untracked(p(b"root_file"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1687
        // Untracked but not deleted
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1688
        assert_eq!(map.len(), 5);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1689
        assert!(map.get(p(b"root_file"))?.is_some());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1690
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1691
        map.set_untracked(p(b"some/file2"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1692
        assert_eq!(map.len(), 5);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1693
        assert_eq!(tracked_descendants(&map, b"some"), 0);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1694
        assert!(map.get(p(b"some/file2"))?.is_some());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1695
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1696
        map.set_untracked(p(b"some/file3"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1697
        assert_eq!(map.len(), 5);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1698
        assert_eq!(tracked_descendants(&map, b"some"), 0);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1699
        assert!(map.get(p(b"some/file3"))?.is_some());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1700
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1701
        Ok(())
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1702
    }
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1703
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1704
    /// Check that copies counter is correctly updated
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1705
    #[test]
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1706
    fn test_copy_source() -> Result<(), DirstateError> {
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1707
        let mut map = OwningDirstateMap::new_empty(vec![]);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1708
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1709
        // Clean file
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1710
        map.reset_state(p(b"files/clean"), true, true, false, false, None)?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1711
        // Merged file
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1712
        map.reset_state(p(b"files/from_p2"), true, true, true, false, None)?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1713
        // Removed file
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1714
        map.reset_state(p(b"removed"), false, true, false, false, None)?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1715
        // Added file
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1716
        map.reset_state(p(b"files/added"), true, false, false, false, None)?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1717
        // Add copy
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1718
        map.copy_map_insert(p(b"files/clean"), p(b"clean_copy_source"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1719
        assert_eq!(map.copy_map_len(), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1720
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1721
        // Copy override
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1722
        map.copy_map_insert(p(b"files/clean"), p(b"other_clean_copy_source"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1723
        assert_eq!(map.copy_map_len(), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1724
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1725
        // Multiple copies
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1726
        map.copy_map_insert(p(b"removed"), p(b"removed_copy_source"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1727
        assert_eq!(map.copy_map_len(), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1728
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1729
        map.copy_map_insert(p(b"files/added"), p(b"added_copy_source"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1730
        assert_eq!(map.copy_map_len(), 3);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1731
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1732
        // Added, so the entry is completely removed
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1733
        map.set_untracked(p(b"files/added"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1734
        assert_does_not_exist(&map, b"files/added");
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1735
        assert_eq!(map.copy_map_len(), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1736
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1737
        // Removed, so the entry is kept around, so is its copy
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1738
        map.set_untracked(p(b"removed"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1739
        assert!(map.get(p(b"removed"))?.is_some());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1740
        assert_eq!(map.copy_map_len(), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1741
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1742
        // Clean, so the entry is kept around, but not its copy
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1743
        map.set_untracked(p(b"files/clean"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1744
        assert!(map.get(p(b"files/clean"))?.is_some());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1745
        assert_eq!(map.copy_map_len(), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1746
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1747
        map.copy_map_insert(p(b"files/from_p2"), p(b"from_p2_copy_source"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1748
        assert_eq!(map.copy_map_len(), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1749
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1750
        // Info from p2, so its copy source info is kept around
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1751
        map.set_untracked(p(b"files/from_p2"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1752
        assert!(map.get(p(b"files/from_p2"))?.is_some());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1753
        assert_eq!(map.copy_map_len(), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1754
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1755
        Ok(())
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1756
    }
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1757
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1758
    /// Test with "on disk" data. For the sake of this test, the "on disk" data
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1759
    /// does not actually come from the disk, but it's opaque to the code being
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1760
    /// tested.
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1761
    #[test]
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1762
    fn test_on_disk() -> Result<(), DirstateError> {
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1763
        // First let's create some data to put "on disk"
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1764
        let mut map = OwningDirstateMap::new_empty(vec![]);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1765
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1766
        // A file that was just added
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1767
        map.set_tracked(p(b"some/nested/added"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1768
        map.copy_map_insert(p(b"some/nested/added"), p(b"added_copy_source"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1769
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1770
        // A file that was removed
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1771
        map.reset_state(
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1772
            p(b"some/nested/removed"),
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1773
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1774
            true,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1775
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1776
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1777
            None,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1778
        )?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1779
        // Only present in p2
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1780
        map.reset_state(
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1781
            p(b"other/p2_info_only"),
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1782
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1783
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1784
            true,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1785
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1786
            None,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1787
        )?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1788
        map.copy_map_insert(
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1789
            p(b"other/p2_info_only"),
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1790
            p(b"other/p2_info_copy_source"),
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1791
        )?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1792
        // A file that was merged
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1793
        map.reset_state(p(b"merged"), true, true, true, false, None)?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1794
        // A file that is added, with info from p2
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1795
        // XXX is that actually possible?
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1796
        map.reset_state(
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1797
            p(b"other/added_with_p2"),
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1798
            true,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1799
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1800
            true,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1801
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1802
            None,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1803
        )?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1804
        // One layer without any files to test deletion cascade
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1805
        // A clean file
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1806
        map.reset_state(
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1807
            p(b"some/other/nested/clean"),
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1808
            true,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1809
            true,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1810
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1811
            false,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1812
            None,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1813
        )?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1814
49147
10b9f11daf15 branching: merge stable into default
Raphaël Gomès <rgomes@octobus.net>
parents: 49143 49145
diff changeset
  1815
        let (packed, metadata, _should_append, _old_data_size) =
10b9f11daf15 branching: merge stable into default
Raphaël Gomès <rgomes@octobus.net>
parents: 49143 49145
diff changeset
  1816
            map.pack_v2(false)?;
49126
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1817
        let packed_len = packed.len();
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1818
        assert!(packed_len > 0);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1819
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1820
        // Recreate "from disk"
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1821
        let mut map = OwningDirstateMap::new_v2(
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1822
            packed,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1823
            packed_len,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1824
            metadata.as_bytes(),
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1825
        )?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1826
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1827
        // Check that everything is accounted for
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1828
        assert!(map.contains_key(p(b"some/nested/added"))?);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1829
        assert!(map.contains_key(p(b"some/nested/removed"))?);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1830
        assert!(map.contains_key(p(b"merged"))?);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1831
        assert!(map.contains_key(p(b"other/p2_info_only"))?);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1832
        assert!(map.contains_key(p(b"other/added_with_p2"))?);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1833
        assert!(map.contains_key(p(b"some/other/nested/clean"))?);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1834
        assert_eq!(
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1835
            map.copy_map_get(p(b"some/nested/added"))?,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1836
            Some(p(b"added_copy_source"))
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1837
        );
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1838
        assert_eq!(
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1839
            map.copy_map_get(p(b"other/p2_info_only"))?,
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1840
            Some(p(b"other/p2_info_copy_source"))
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1841
        );
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1842
        assert_eq!(tracked_descendants(&map, b"some"), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1843
        assert_eq!(descendants_with_an_entry(&map, b"some"), 3);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1844
        assert_eq!(tracked_descendants(&map, b"other"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1845
        assert_eq!(descendants_with_an_entry(&map, b"other"), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1846
        assert_eq!(tracked_descendants(&map, b"some/other"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1847
        assert_eq!(descendants_with_an_entry(&map, b"some/other"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1848
        assert_eq!(tracked_descendants(&map, b"some/other/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1849
        assert_eq!(descendants_with_an_entry(&map, b"some/other/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1850
        assert_eq!(tracked_descendants(&map, b"some/nested"), 1);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1851
        assert_eq!(descendants_with_an_entry(&map, b"some/nested"), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1852
        assert_eq!(map.len(), 6);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1853
        assert_eq!(map.get_map().unreachable_bytes, 0);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1854
        assert_eq!(map.copy_map_len(), 2);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1855
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1856
        // Shouldn't change anything since it's already not tracked
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1857
        map.set_untracked(p(b"some/nested/removed"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1858
        assert_eq!(map.get_map().unreachable_bytes, 0);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1859
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
  1860
        if let ChildNodes::InMemory(_) = map.get_map().root {
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
  1861
            panic!("root should not have been mutated")
49126
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1862
        }
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1863
        // We haven't mutated enough (nothing, actually), we should still be in
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1864
        // the append strategy
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1865
        assert!(map.get_map().write_should_append());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1866
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1867
        // But this mutates the structure, so there should be unreachable_bytes
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1868
        assert!(map.set_untracked(p(b"some/nested/added"))?);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1869
        let unreachable_bytes = map.get_map().unreachable_bytes;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1870
        assert!(unreachable_bytes > 0);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1871
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
  1872
        if let ChildNodes::OnDisk(_) = map.get_map().root {
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
  1873
            panic!("root should have been mutated")
49126
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1874
        }
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1875
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1876
        // This should not mutate the structure either, since `root` has
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1877
        // already been mutated along with its direct children.
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1878
        map.set_untracked(p(b"merged"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1879
        assert_eq!(map.get_map().unreachable_bytes, unreachable_bytes);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1880
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
  1881
        if let NodeRef::InMemory(_, _) =
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
  1882
            map.get_map().get_node(p(b"other/added_with_p2"))?.unwrap()
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
  1883
        {
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
  1884
            panic!("'other/added_with_p2' should not have been mutated")
49126
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1885
        }
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1886
        // But this should, since it's in a different path
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1887
        // than `<root>some/nested/add`
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1888
        map.set_untracked(p(b"other/added_with_p2"))?;
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1889
        assert!(map.get_map().unreachable_bytes > unreachable_bytes);
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1890
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
  1891
        if let NodeRef::OnDisk(_) =
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
  1892
            map.get_map().get_node(p(b"other/added_with_p2"))?.unwrap()
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
  1893
        {
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49924
diff changeset
  1894
            panic!("'other/added_with_p2' should have been mutated")
49126
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1895
        }
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1896
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1897
        // We have rewritten most of the tree, we should create a new file
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1898
        assert!(!map.get_map().write_should_append());
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1899
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1900
        Ok(())
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1901
    }
e7b74bb602a4 rust-dirstatemap: add unit tests
Raphaël Gomès <rgomes@octobus.net>
parents: 49125
diff changeset
  1902
}