rust/hg-core/src/dirstate/dirstate_map.rs
author Simon Sapin <simon.sapin@octobus.net>
Tue, 30 Mar 2021 14:15:23 +0200
changeset 47093 787ff5d21bcd
parent 46890 441024b279a6
child 47101 5d62243c7732
permissions -rw-r--r--
dirstate-tree: Make Rust DirstateMap bindings go through a trait object This changeset starts a series that adds an experiment to make status faster by changing the dirstate (first only in memory and later also on disk) to be shaped as a tree matching the directory structure, instead of the current flat collection of entries. The status algorithm can then traverse this tree dirstate at the same time as it traverses the filesystem. We (Octobus) have made prototypes that show promising results but are prone to bitrot. We would like to start upstreaming some experimental Rust code that goes in this direction, but to avoid disrupting users it should only be enabled by some run-time opt-in while keeping the existing dirstate structure and status algorithm as-is. The `DirstateMap` type and `status` function look like the appropriate boundary. This adds a new trait that abstracts everything Python bindings need and makes those bindings go through a `dyn` trait object. Later we’ll have two implementations of this trait, and the same bindings can use either. Differential Revision: https://phab.mercurial-scm.org/D10362
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     1
// dirstate_map.rs
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     2
//
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     3
// Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     4
//
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     7
46440
776b97179c06 rust: Remove DirstateParseError and ListDirstateTrackedFilesError
Simon Sapin <simon.sapin@octobus.net>
parents: 46227
diff changeset
     8
use crate::errors::HgError;
46595
98a455a62699 rust: Make `DirstateParents`’s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46594
diff changeset
     9
use crate::revlog::node::NULL_NODE;
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    10
use crate::{
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 42957
diff changeset
    11
    dirstate::{parsers::PARENT_SIZE, EntryState, SIZE_FROM_OTHER_PARENT},
42840
b1b984f9c01d rust-utils: add normalize_case util to mirror Python one
Raphaël Gomès <rgomes@octobus.net>
parents: 42802
diff changeset
    12
    pack_dirstate, parse_dirstate,
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 42957
diff changeset
    13
    utils::{
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 42957
diff changeset
    14
        files::normalize_case,
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 42957
diff changeset
    15
        hg_path::{HgPath, HgPathBuf},
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 42957
diff changeset
    16
    },
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
    17
    CopyMap, DirsMultiset, DirstateEntry, DirstateError, DirstateMapError,
46440
776b97179c06 rust: Remove DirstateParseError and ListDirstateTrackedFilesError
Simon Sapin <simon.sapin@octobus.net>
parents: 46227
diff changeset
    18
    DirstateParents, FastHashMap, StateMap,
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    19
};
45558
80bf7b1ada15 rust-dirstatemap: add #[timed] to dirstatemap read for comparison
Raphaël Gomès <rgomes@octobus.net>
parents: 45531
diff changeset
    20
use micro_timer::timed;
43826
5ac243a92e37 rust-performance: introduce FastHashMap type alias for HashMap
Raphaël Gomès <rgomes@octobus.net>
parents: 43788
diff changeset
    21
use std::collections::HashSet;
42799
5399532510ae rust: simply use TryInto to convert slice to array
Yuya Nishihara <yuya@tcha.org>
parents: 42798
diff changeset
    22
use std::convert::TryInto;
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    23
use std::iter::FromIterator;
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    24
use std::ops::Deref;
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    25
use std::time::Duration;
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    26
43826
5ac243a92e37 rust-performance: introduce FastHashMap type alias for HashMap
Raphaël Gomès <rgomes@octobus.net>
parents: 43788
diff changeset
    27
pub type FileFoldMap = FastHashMap<HgPathBuf, HgPathBuf>;
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    28
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    29
const MTIME_UNSET: i32 = -1;
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    30
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    31
#[derive(Default)]
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    32
pub struct DirstateMap {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    33
    state_map: StateMap,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    34
    pub copy_map: CopyMap,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    35
    file_fold_map: Option<FileFoldMap>,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    36
    pub dirs: Option<DirsMultiset>,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    37
    pub all_dirs: Option<DirsMultiset>,
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
    38
    non_normal_set: Option<HashSet<HgPathBuf>>,
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
    39
    other_parent_set: Option<HashSet<HgPathBuf>>,
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    40
    parents: Option<DirstateParents>,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    41
    dirty_parents: bool,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    42
}
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    43
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    44
/// Should only really be used in python interface code, for clarity
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    45
impl Deref for DirstateMap {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    46
    type Target = StateMap;
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    47
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    48
    fn deref(&self) -> &Self::Target {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    49
        &self.state_map
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    50
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    51
}
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    52
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
    53
impl FromIterator<(HgPathBuf, DirstateEntry)> for DirstateMap {
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
    54
    fn from_iter<I: IntoIterator<Item = (HgPathBuf, DirstateEntry)>>(
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
    55
        iter: I,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
    56
    ) -> Self {
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    57
        Self {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    58
            state_map: iter.into_iter().collect(),
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    59
            ..Self::default()
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    60
        }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    61
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    62
}
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    63
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    64
impl DirstateMap {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    65
    pub fn new() -> Self {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    66
        Self::default()
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    67
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    68
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    69
    pub fn clear(&mut self) {
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
    70
        self.state_map = StateMap::default();
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    71
        self.copy_map.clear();
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    72
        self.file_fold_map = None;
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
    73
        self.non_normal_set = None;
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
    74
        self.other_parent_set = None;
42801
1a535313ad1b rust-dirstate: remove excessive clone() of parameter and return value
Yuya Nishihara <yuya@tcha.org>
parents: 42799
diff changeset
    75
        self.set_parents(&DirstateParents {
46595
98a455a62699 rust: Make `DirstateParents`’s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46594
diff changeset
    76
            p1: NULL_NODE,
98a455a62699 rust: Make `DirstateParents`’s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46594
diff changeset
    77
            p2: NULL_NODE,
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    78
        })
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    79
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    80
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    81
    /// Add a tracked file to the dirstate
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    82
    pub fn add_file(
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    83
        &mut self,
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
    84
        filename: &HgPath,
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    85
        old_state: EntryState,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    86
        entry: DirstateEntry,
43788
1fe2e574616e rust-dirs: address failing tests for `dirs` impl with a temporary fix
Raphaël Gomès <rgomes@octobus.net>
parents: 43605
diff changeset
    87
    ) -> Result<(), DirstateMapError> {
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
    88
        if old_state == EntryState::Unknown || old_state == EntryState::Removed
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
    89
        {
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    90
            if let Some(ref mut dirs) = self.dirs {
43788
1fe2e574616e rust-dirs: address failing tests for `dirs` impl with a temporary fix
Raphaël Gomès <rgomes@octobus.net>
parents: 43605
diff changeset
    91
                dirs.add_path(filename)?;
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    92
            }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    93
        }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    94
        if old_state == EntryState::Unknown {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    95
            if let Some(ref mut all_dirs) = self.all_dirs {
43788
1fe2e574616e rust-dirs: address failing tests for `dirs` impl with a temporary fix
Raphaël Gomès <rgomes@octobus.net>
parents: 43605
diff changeset
    96
                all_dirs.add_path(filename)?;
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    97
            }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    98
        }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    99
        self.state_map.insert(filename.to_owned(), entry.to_owned());
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   100
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   101
        if entry.state != EntryState::Normal || entry.mtime == MTIME_UNSET {
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   102
            self.get_non_normal_other_parent_entries()
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   103
                .0
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   104
                .insert(filename.to_owned());
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   105
        }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   106
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 42957
diff changeset
   107
        if entry.size == SIZE_FROM_OTHER_PARENT {
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   108
            self.get_non_normal_other_parent_entries()
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   109
                .1
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   110
                .insert(filename.to_owned());
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   111
        }
43788
1fe2e574616e rust-dirs: address failing tests for `dirs` impl with a temporary fix
Raphaël Gomès <rgomes@octobus.net>
parents: 43605
diff changeset
   112
        Ok(())
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   113
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   114
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   115
    /// Mark a file as removed in the dirstate.
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   116
    ///
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   117
    /// The `size` parameter is used to store sentinel values that indicate
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   118
    /// the file's previous state.  In the future, we should refactor this
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   119
    /// to be more explicit about what that state is.
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   120
    pub fn remove_file(
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   121
        &mut self,
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   122
        filename: &HgPath,
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   123
        old_state: EntryState,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   124
        size: i32,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   125
    ) -> Result<(), DirstateMapError> {
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   126
        if old_state != EntryState::Unknown && old_state != EntryState::Removed
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   127
        {
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   128
            if let Some(ref mut dirs) = self.dirs {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   129
                dirs.delete_path(filename)?;
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   130
            }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   131
        }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   132
        if old_state == EntryState::Unknown {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   133
            if let Some(ref mut all_dirs) = self.all_dirs {
43863
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   134
                all_dirs.add_path(filename)?;
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   135
            }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   136
        }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   137
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   138
        if let Some(ref mut file_fold_map) = self.file_fold_map {
42840
b1b984f9c01d rust-utils: add normalize_case util to mirror Python one
Raphaël Gomès <rgomes@octobus.net>
parents: 42802
diff changeset
   139
            file_fold_map.remove(&normalize_case(filename));
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   140
        }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   141
        self.state_map.insert(
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   142
            filename.to_owned(),
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   143
            DirstateEntry {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   144
                state: EntryState::Removed,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   145
                mode: 0,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   146
                size,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   147
                mtime: 0,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   148
            },
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   149
        );
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   150
        self.get_non_normal_other_parent_entries()
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   151
            .0
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   152
            .insert(filename.to_owned());
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   153
        Ok(())
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   154
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   155
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   156
    /// Remove a file from the dirstate.
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   157
    /// Returns `true` if the file was previously recorded.
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   158
    pub fn drop_file(
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   159
        &mut self,
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   160
        filename: &HgPath,
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   161
        old_state: EntryState,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   162
    ) -> Result<bool, DirstateMapError> {
42795
8d2d5dfa07f5 rust-dirstate: remove too abstracted way of getting &[u8]
Yuya Nishihara <yuya@tcha.org>
parents: 42753
diff changeset
   163
        let exists = self.state_map.remove(filename).is_some();
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   164
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   165
        if exists {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   166
            if old_state != EntryState::Removed {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   167
                if let Some(ref mut dirs) = self.dirs {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   168
                    dirs.delete_path(filename)?;
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   169
                }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   170
            }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   171
            if let Some(ref mut all_dirs) = self.all_dirs {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   172
                all_dirs.delete_path(filename)?;
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   173
            }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   174
        }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   175
        if let Some(ref mut file_fold_map) = self.file_fold_map {
42840
b1b984f9c01d rust-utils: add normalize_case util to mirror Python one
Raphaël Gomès <rgomes@octobus.net>
parents: 42802
diff changeset
   176
            file_fold_map.remove(&normalize_case(filename));
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   177
        }
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   178
        self.get_non_normal_other_parent_entries()
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   179
            .0
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   180
            .remove(filename);
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   181
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   182
        Ok(exists)
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   183
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   184
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   185
    pub fn clear_ambiguous_times(
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   186
        &mut self,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   187
        filenames: Vec<HgPathBuf>,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   188
        now: i32,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   189
    ) {
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   190
        for filename in filenames {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   191
            let mut changed = false;
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   192
            if let Some(entry) = self.state_map.get_mut(&filename) {
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   193
                if entry.state == EntryState::Normal && entry.mtime == now {
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   194
                    changed = true;
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   195
                    *entry = DirstateEntry {
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   196
                        mtime: MTIME_UNSET,
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   197
                        ..*entry
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   198
                    };
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   199
                }
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   200
            }
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   201
            if changed {
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   202
                self.get_non_normal_other_parent_entries()
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   203
                    .0
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   204
                    .insert(filename.to_owned());
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   205
            }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   206
        }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   207
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   208
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   209
    pub fn non_normal_entries_remove(
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   210
        &mut self,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   211
        key: impl AsRef<HgPath>,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   212
    ) -> bool {
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   213
        self.get_non_normal_other_parent_entries()
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   214
            .0
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   215
            .remove(key.as_ref())
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   216
    }
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   217
    pub fn non_normal_entries_union(
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   218
        &mut self,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   219
        other: HashSet<HgPathBuf>,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   220
    ) -> Vec<HgPathBuf> {
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   221
        self.get_non_normal_other_parent_entries()
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   222
            .0
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   223
            .union(&other)
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44416
diff changeset
   224
            .map(ToOwned::to_owned)
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   225
            .collect()
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   226
    }
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   227
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   228
    pub fn get_non_normal_other_parent_entries(
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   229
        &mut self,
44362
c089a0947f3e rust-dirstatemap: directly return `non_normal` and `other_entries`
Raphaël Gomès <rgomes@octobus.net>
parents: 44293
diff changeset
   230
    ) -> (&mut HashSet<HgPathBuf>, &mut HashSet<HgPathBuf>) {
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   231
        self.set_non_normal_other_parent_entries(false);
44362
c089a0947f3e rust-dirstatemap: directly return `non_normal` and `other_entries`
Raphaël Gomès <rgomes@octobus.net>
parents: 44293
diff changeset
   232
        (
c089a0947f3e rust-dirstatemap: directly return `non_normal` and `other_entries`
Raphaël Gomès <rgomes@octobus.net>
parents: 44293
diff changeset
   233
            self.non_normal_set.as_mut().unwrap(),
c089a0947f3e rust-dirstatemap: directly return `non_normal` and `other_entries`
Raphaël Gomès <rgomes@octobus.net>
parents: 44293
diff changeset
   234
            self.other_parent_set.as_mut().unwrap(),
c089a0947f3e rust-dirstatemap: directly return `non_normal` and `other_entries`
Raphaël Gomès <rgomes@octobus.net>
parents: 44293
diff changeset
   235
        )
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   236
    }
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   237
44416
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   238
    /// Useful to get immutable references to those sets in contexts where
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   239
    /// you only have an immutable reference to the `DirstateMap`, like when
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   240
    /// sharing references with Python.
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   241
    ///
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   242
    /// TODO, get rid of this along with the other "setter/getter" stuff when
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   243
    /// a nice typestate plan is defined.
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   244
    ///
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   245
    /// # Panics
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   246
    ///
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   247
    /// Will panic if either set is `None`.
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   248
    pub fn get_non_normal_other_parent_entries_panic(
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   249
        &self,
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   250
    ) -> (&HashSet<HgPathBuf>, &HashSet<HgPathBuf>) {
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   251
        (
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   252
            self.non_normal_set.as_ref().unwrap(),
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   253
            self.other_parent_set.as_ref().unwrap(),
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   254
        )
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   255
    }
8ac5726d695d rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)
Raphaël Gomès <rgomes@octobus.net>
parents: 44362
diff changeset
   256
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   257
    pub fn set_non_normal_other_parent_entries(&mut self, force: bool) {
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   258
        if !force
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   259
            && self.non_normal_set.is_some()
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   260
            && self.other_parent_set.is_some()
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   261
        {
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   262
            return;
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   263
        }
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   264
        let mut non_normal = HashSet::new();
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   265
        let mut other_parent = HashSet::new();
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   266
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   267
        for (
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   268
            filename,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   269
            DirstateEntry {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   270
                state, size, mtime, ..
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   271
            },
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   272
        ) in self.state_map.iter()
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   273
        {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   274
            if *state != EntryState::Normal || *mtime == MTIME_UNSET {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   275
                non_normal.insert(filename.to_owned());
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   276
            }
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   277
            if *state == EntryState::Normal && *size == SIZE_FROM_OTHER_PARENT
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   278
            {
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   279
                other_parent.insert(filename.to_owned());
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   280
            }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   281
        }
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   282
        self.non_normal_set = Some(non_normal);
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   283
        self.other_parent_set = Some(other_parent);
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   284
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   285
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   286
    /// Both of these setters and their uses appear to be the simplest way to
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   287
    /// emulate a Python lazy property, but it is ugly and unidiomatic.
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   288
    /// TODO One day, rewriting this struct using the typestate might be a
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   289
    /// good idea.
43863
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   290
    pub fn set_all_dirs(&mut self) -> Result<(), DirstateMapError> {
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   291
        if self.all_dirs.is_none() {
47093
787ff5d21bcd dirstate-tree: Make Rust DirstateMap bindings go through a trait object
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
   292
            self.all_dirs = Some(DirsMultiset::from_dirstate(
787ff5d21bcd dirstate-tree: Make Rust DirstateMap bindings go through a trait object
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
   293
                self.state_map.iter(),
787ff5d21bcd dirstate-tree: Make Rust DirstateMap bindings go through a trait object
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
   294
                None,
787ff5d21bcd dirstate-tree: Make Rust DirstateMap bindings go through a trait object
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
   295
            )?);
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   296
        }
43863
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   297
        Ok(())
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   298
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   299
43863
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   300
    pub fn set_dirs(&mut self) -> Result<(), DirstateMapError> {
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   301
        if self.dirs.is_none() {
42802
2e1f74cc3350 rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents: 42801
diff changeset
   302
            self.dirs = Some(DirsMultiset::from_dirstate(
2e1f74cc3350 rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents: 42801
diff changeset
   303
                &self.state_map,
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   304
                Some(EntryState::Removed),
43863
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   305
            )?);
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   306
        }
43863
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   307
        Ok(())
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   308
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   309
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   310
    pub fn has_tracked_dir(
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   311
        &mut self,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   312
        directory: &HgPath,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   313
    ) -> Result<bool, DirstateMapError> {
43863
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   314
        self.set_dirs()?;
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   315
        Ok(self.dirs.as_ref().unwrap().contains(directory))
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   316
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   317
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   318
    pub fn has_dir(
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   319
        &mut self,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   320
        directory: &HgPath,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   321
    ) -> Result<bool, DirstateMapError> {
43863
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   322
        self.set_all_dirs()?;
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   323
        Ok(self.all_dirs.as_ref().unwrap().contains(directory))
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   324
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   325
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   326
    pub fn parents(
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   327
        &mut self,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   328
        file_contents: &[u8],
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   329
    ) -> Result<&DirstateParents, DirstateError> {
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   330
        if let Some(ref parents) = self.parents {
42801
1a535313ad1b rust-dirstate: remove excessive clone() of parameter and return value
Yuya Nishihara <yuya@tcha.org>
parents: 42799
diff changeset
   331
            return Ok(parents);
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   332
        }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   333
        let parents;
42798
99dff4264524 rust-dirstate: use PARENT_SIZE constant where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 42797
diff changeset
   334
        if file_contents.len() == PARENT_SIZE * 2 {
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   335
            parents = DirstateParents {
42799
5399532510ae rust: simply use TryInto to convert slice to array
Yuya Nishihara <yuya@tcha.org>
parents: 42798
diff changeset
   336
                p1: file_contents[..PARENT_SIZE].try_into().unwrap(),
5399532510ae rust: simply use TryInto to convert slice to array
Yuya Nishihara <yuya@tcha.org>
parents: 42798
diff changeset
   337
                p2: file_contents[PARENT_SIZE..PARENT_SIZE * 2]
5399532510ae rust: simply use TryInto to convert slice to array
Yuya Nishihara <yuya@tcha.org>
parents: 42798
diff changeset
   338
                    .try_into()
5399532510ae rust: simply use TryInto to convert slice to array
Yuya Nishihara <yuya@tcha.org>
parents: 42798
diff changeset
   339
                    .unwrap(),
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   340
            };
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   341
        } else if file_contents.is_empty() {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   342
            parents = DirstateParents {
46595
98a455a62699 rust: Make `DirstateParents`’s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46594
diff changeset
   343
                p1: NULL_NODE,
98a455a62699 rust: Make `DirstateParents`’s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46594
diff changeset
   344
                p2: NULL_NODE,
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   345
            };
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   346
        } else {
46440
776b97179c06 rust: Remove DirstateParseError and ListDirstateTrackedFilesError
Simon Sapin <simon.sapin@octobus.net>
parents: 46227
diff changeset
   347
            return Err(
776b97179c06 rust: Remove DirstateParseError and ListDirstateTrackedFilesError
Simon Sapin <simon.sapin@octobus.net>
parents: 46227
diff changeset
   348
                HgError::corrupted("Dirstate appears to be damaged").into()
776b97179c06 rust: Remove DirstateParseError and ListDirstateTrackedFilesError
Simon Sapin <simon.sapin@octobus.net>
parents: 46227
diff changeset
   349
            );
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   350
        }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   351
42801
1a535313ad1b rust-dirstate: remove excessive clone() of parameter and return value
Yuya Nishihara <yuya@tcha.org>
parents: 42799
diff changeset
   352
        self.parents = Some(parents);
1a535313ad1b rust-dirstate: remove excessive clone() of parameter and return value
Yuya Nishihara <yuya@tcha.org>
parents: 42799
diff changeset
   353
        Ok(self.parents.as_ref().unwrap())
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   354
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   355
42801
1a535313ad1b rust-dirstate: remove excessive clone() of parameter and return value
Yuya Nishihara <yuya@tcha.org>
parents: 42799
diff changeset
   356
    pub fn set_parents(&mut self, parents: &DirstateParents) {
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   357
        self.parents = Some(parents.clone());
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   358
        self.dirty_parents = true;
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   359
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   360
45558
80bf7b1ada15 rust-dirstatemap: add #[timed] to dirstatemap read for comparison
Raphaël Gomès <rgomes@octobus.net>
parents: 45531
diff changeset
   361
    #[timed]
46594
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
   362
    pub fn read<'a>(
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   363
        &mut self,
46594
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
   364
        file_contents: &'a [u8],
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
   365
    ) -> Result<Option<&'a DirstateParents>, DirstateError> {
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   366
        if file_contents.is_empty() {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   367
            return Ok(None);
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   368
        }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   369
45357
27424779c5b8 hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
   370
        let (parents, entries, copies) = parse_dirstate(file_contents)?;
27424779c5b8 hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
   371
        self.state_map.extend(
27424779c5b8 hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
   372
            entries
27424779c5b8 hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
   373
                .into_iter()
27424779c5b8 hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
   374
                .map(|(path, entry)| (path.to_owned(), entry)),
27424779c5b8 hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
   375
        );
27424779c5b8 hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
   376
        self.copy_map.extend(
27424779c5b8 hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
   377
            copies
27424779c5b8 hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
   378
                .into_iter()
27424779c5b8 hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
   379
                .map(|(path, copy)| (path.to_owned(), copy.to_owned())),
27424779c5b8 hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
   380
        );
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   381
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   382
        if !self.dirty_parents {
42801
1a535313ad1b rust-dirstate: remove excessive clone() of parameter and return value
Yuya Nishihara <yuya@tcha.org>
parents: 42799
diff changeset
   383
            self.set_parents(&parents);
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   384
        }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   385
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   386
        Ok(Some(parents))
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   387
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   388
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   389
    pub fn pack(
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   390
        &mut self,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   391
        parents: DirstateParents,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   392
        now: Duration,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   393
    ) -> Result<Vec<u8>, DirstateError> {
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   394
        let packed =
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   395
            pack_dirstate(&mut self.state_map, &self.copy_map, parents, now)?;
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   396
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   397
        self.dirty_parents = false;
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   398
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   399
        self.set_non_normal_other_parent_entries(true);
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   400
        Ok(packed)
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   401
    }
42801
1a535313ad1b rust-dirstate: remove excessive clone() of parameter and return value
Yuya Nishihara <yuya@tcha.org>
parents: 42799
diff changeset
   402
    pub fn build_file_fold_map(&mut self) -> &FileFoldMap {
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   403
        if let Some(ref file_fold_map) = self.file_fold_map {
42801
1a535313ad1b rust-dirstate: remove excessive clone() of parameter and return value
Yuya Nishihara <yuya@tcha.org>
parents: 42799
diff changeset
   404
            return file_fold_map;
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   405
        }
43826
5ac243a92e37 rust-performance: introduce FastHashMap type alias for HashMap
Raphaël Gomès <rgomes@octobus.net>
parents: 43788
diff changeset
   406
        let mut new_file_fold_map = FileFoldMap::default();
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   407
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   408
        for (filename, DirstateEntry { state, .. }) in self.state_map.iter() {
46227
5bae4bc9bd42 rust: fix file folding map
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 45610
diff changeset
   409
            if *state != EntryState::Removed {
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   410
                new_file_fold_map
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   411
                    .insert(normalize_case(&filename), filename.to_owned());
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   412
            }
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   413
        }
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   414
        self.file_fold_map = Some(new_file_fold_map);
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   415
        self.file_fold_map.as_ref().unwrap()
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45588
diff changeset
   416
    }
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   417
}
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   418
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   419
#[cfg(test)]
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   420
mod tests {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   421
    use super::*;
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   422
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   423
    #[test]
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   424
    fn test_dirs_multiset() {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   425
        let mut map = DirstateMap::new();
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   426
        assert!(map.dirs.is_none());
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   427
        assert!(map.all_dirs.is_none());
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   428
43863
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   429
        assert_eq!(map.has_dir(HgPath::new(b"nope")).unwrap(), false);
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   430
        assert!(map.all_dirs.is_some());
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   431
        assert!(map.dirs.is_none());
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   432
43863
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents: 43826
diff changeset
   433
        assert_eq!(map.has_tracked_dir(HgPath::new(b"nope")).unwrap(), false);
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   434
        assert!(map.dirs.is_some());
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   435
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   436
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   437
    #[test]
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   438
    fn test_add_file() {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   439
        let mut map = DirstateMap::new();
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   440
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   441
        assert_eq!(0, map.len());
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   442
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   443
        map.add_file(
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   444
            HgPath::new(b"meh"),
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   445
            EntryState::Normal,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   446
            DirstateEntry {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   447
                state: EntryState::Normal,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   448
                mode: 1337,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   449
                mtime: 1337,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   450
                size: 1337,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   451
            },
43890
d8a96cebf75d rust-warnings: fix warnings in tests
Raphaël Gomès <rgomes@octobus.net>
parents: 43863
diff changeset
   452
        )
d8a96cebf75d rust-warnings: fix warnings in tests
Raphaël Gomès <rgomes@octobus.net>
parents: 43863
diff changeset
   453
        .unwrap();
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   454
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   455
        assert_eq!(1, map.len());
44362
c089a0947f3e rust-dirstatemap: directly return `non_normal` and `other_entries`
Raphaël Gomès <rgomes@octobus.net>
parents: 44293
diff changeset
   456
        assert_eq!(0, map.get_non_normal_other_parent_entries().0.len());
c089a0947f3e rust-dirstatemap: directly return `non_normal` and `other_entries`
Raphaël Gomès <rgomes@octobus.net>
parents: 44293
diff changeset
   457
        assert_eq!(0, map.get_non_normal_other_parent_entries().1.len());
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   458
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   459
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   460
    #[test]
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   461
    fn test_non_normal_other_parent_entries() {
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   462
        let mut map: DirstateMap = [
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   463
            (b"f1", (EntryState::Removed, 1337, 1337, 1337)),
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   464
            (b"f2", (EntryState::Normal, 1337, 1337, -1)),
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   465
            (b"f3", (EntryState::Normal, 1337, 1337, 1337)),
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   466
            (b"f4", (EntryState::Normal, 1337, -2, 1337)),
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   467
            (b"f5", (EntryState::Added, 1337, 1337, 1337)),
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   468
            (b"f6", (EntryState::Added, 1337, 1337, -1)),
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   469
            (b"f7", (EntryState::Merged, 1337, 1337, -1)),
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   470
            (b"f8", (EntryState::Merged, 1337, 1337, 1337)),
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   471
            (b"f9", (EntryState::Merged, 1337, -2, 1337)),
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   472
            (b"fa", (EntryState::Added, 1337, -2, 1337)),
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   473
            (b"fb", (EntryState::Removed, 1337, -2, 1337)),
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   474
        ]
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   475
        .iter()
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   476
        .map(|(fname, (state, mode, size, mtime))| {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   477
            (
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   478
                HgPathBuf::from_bytes(fname.as_ref()),
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   479
                DirstateEntry {
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   480
                    state: *state,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   481
                    mode: *mode,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   482
                    size: *size,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   483
                    mtime: *mtime,
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   484
                },
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   485
            )
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   486
        })
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   487
        .collect();
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   488
44362
c089a0947f3e rust-dirstatemap: directly return `non_normal` and `other_entries`
Raphaël Gomès <rgomes@octobus.net>
parents: 44293
diff changeset
   489
        let mut non_normal = [
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   490
            b"f1", b"f2", b"f5", b"f6", b"f7", b"f8", b"f9", b"fa", b"fb",
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   491
        ]
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   492
        .iter()
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   493
        .map(|x| HgPathBuf::from_bytes(x.as_ref()))
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   494
        .collect();
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   495
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   496
        let mut other_parent = HashSet::new();
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents: 42840
diff changeset
   497
        other_parent.insert(HgPathBuf::from_bytes(b"f4"));
44293
83b2b829c94e rust-dirstatemap: cache non normal and other parent set
Raphaël Gomès <rgomes@octobus.net>
parents: 43890
diff changeset
   498
        let entries = map.get_non_normal_other_parent_entries();
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   499
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   500
        assert_eq!(
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   501
            (&mut non_normal, &mut other_parent),
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   502
            (entries.0, entries.1)
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45558
diff changeset
   503
        );
42753
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   504
    }
fce6dc93a510 rust-dirstate: rust implementation of dirstatemap
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   505
}