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