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