##// END OF EJS Templates
upgrade: implement partial upgrade for upgrading persistent-nodemap...
upgrade: implement partial upgrade for upgrading persistent-nodemap Upgrading repositories to use persistent nodemap should be fast and easy as it requires only two things: 1) Updating the requirements 2) Writing a persistent-nodemap on disk For both of the steps above, we don't need to edit existing revlogs. This patch makes upgrade only do the above mentioned two steps if we are only upgarding to use persistent-nodemap feature. Since `nodemap.persist_nodemap()` assumes that there exists a nodemap file for the given revlog if we are trying to call it, this patch adds `force` argument to create a file if does not exist which is true in our upgrade case. The test changes demonstrate that we no longer write nodemap files for manifest after upgrade which I think is desirable. Differential Revision: https://phab.mercurial-scm.org/D9936

File last commit:

r47169:776b9717 default
r47199:98e39f04 default
Show More
parsers.rs
157 lines | 4.6 KiB | application/rls-services+xml | RustLexer
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 // parsers.rs
//
// Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
//! Bindings for the `hg::dirstate::parsers` module provided by the
//! `hg-core` package.
//!
//! From Python, this will be seen as `mercurial.rustext.parsers`
use cpython::{
exc, PyBytes, PyDict, PyErr, PyInt, PyModule, PyResult, PyTuple, Python,
Yuya Nishihara
rust-parsers: fix unboxing of PyInt on Python 3...
r43061 PythonObject, ToPyObject,
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 };
use hg::{
Antoine Cezar
hg-core: make parse_dirstate return references rather than update hashmaps...
r45916 pack_dirstate, parse_dirstate, utils::hg_path::HgPathBuf, DirstateEntry,
Simon Sapin
rust: Remove DirstateParseError and ListDirstateTrackedFilesError...
r47169 DirstateParents, FastHashMap, PARENT_SIZE,
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 };
Yuya Nishihara
rust: simply use TryInto to convert slice to array...
r43067 use std::convert::TryInto;
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992
Yuya Nishihara
rust-cpython: add wrapper around decapsule_make_dirstate_tuple()...
r43479 use crate::dirstate::{extract_dirstate, make_dirstate_tuple};
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 use std::time::Duration;
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992
fn parse_dirstate_wrapper(
py: Python,
dmap: PyDict,
copymap: PyDict,
st: PyBytes,
) -> PyResult<PyTuple> {
Antoine Cezar
hg-core: make parse_dirstate return references rather than update hashmaps...
r45916 match parse_dirstate(st.data(py)) {
Ok((parents, entries, copies)) => {
let dirstate_map: FastHashMap<HgPathBuf, DirstateEntry> = entries
.into_iter()
.map(|(path, entry)| (path.to_owned(), entry))
.collect();
let copy_map: FastHashMap<HgPathBuf, HgPathBuf> = copies
.into_iter()
.map(|(path, copy)| (path.to_owned(), copy.to_owned()))
.collect();
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993
Yuya Nishihara
rust-cpython: add wrapper around decapsule_make_dirstate_tuple()...
r43479 for (filename, entry) in &dirstate_map {
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 dmap.set_item(
py,
Raphaël Gomès
rust: do a clippy pass...
r45500 PyBytes::new(py, filename.as_bytes()),
Yuya Nishihara
rust-cpython: add wrapper around decapsule_make_dirstate_tuple()...
r43479 make_dirstate_tuple(py, entry)?,
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 )?;
}
Antoine Cezar
hg-core: make parse_dirstate return references rather than update hashmaps...
r45916 for (path, copy_path) in copy_map {
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 copymap.set_item(
py,
Raphaël Gomès
rust: do a clippy pass...
r45500 PyBytes::new(py, path.as_bytes()),
PyBytes::new(py, copy_path.as_bytes()),
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 )?;
}
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 Ok(
(PyBytes::new(py, &parents.p1), PyBytes::new(py, &parents.p2))
.to_py_object(py),
)
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 }
Simon Sapin
rust: Remove DirstateParseError and ListDirstateTrackedFilesError...
r47169 Err(e) => Err(PyErr::new::<exc::ValueError, _>(py, e.to_string())),
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 }
}
fn pack_dirstate_wrapper(
py: Python,
dmap: PyDict,
copymap: PyDict,
pl: PyTuple,
now: PyInt,
) -> PyResult<PyBytes> {
let p1 = pl.get_item(py, 0).extract::<PyBytes>(py)?;
let p1: &[u8] = p1.data(py);
let p2 = pl.get_item(py, 1).extract::<PyBytes>(py)?;
let p2: &[u8] = p2.data(py);
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let mut dirstate_map = extract_dirstate(py, &dmap)?;
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992
Raphaël Gomès
rust-performance: introduce FastHashMap type alias for HashMap...
r44278 let copies: Result<FastHashMap<HgPathBuf, HgPathBuf>, PyErr> = copymap
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 .items(py)
.iter()
.map(|(key, value)| {
Ok((
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPathBuf::from_bytes(key.extract::<PyBytes>(py)?.data(py)),
HgPathBuf::from_bytes(value.extract::<PyBytes>(py)?.data(py)),
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 ))
})
.collect();
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 if p1.len() != PARENT_SIZE || p2.len() != PARENT_SIZE {
return Err(PyErr::new::<exc::ValueError, _>(
py,
"expected a 20-byte hash".to_string(),
));
}
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 match pack_dirstate(
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 &mut dirstate_map,
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 &copies?,
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 DirstateParents {
Yuya Nishihara
rust: simply use TryInto to convert slice to array...
r43067 p1: p1.try_into().unwrap(),
p2: p2.try_into().unwrap(),
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 },
Yuya Nishihara
rust-parsers: fix unboxing of PyInt on Python 3...
r43061 Duration::from_secs(now.as_object().extract::<u64>(py)?),
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 ) {
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 Ok(packed) => {
Raphaël Gomès
rust: start plugging the dirstate tree behind a feature gate...
r46185 for (filename, entry) in dirstate_map.iter() {
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 dmap.set_item(
py,
Raphaël Gomès
rust: do a clippy pass...
r45500 PyBytes::new(py, filename.as_bytes()),
Raphaël Gomès
rust: start plugging the dirstate tree behind a feature gate...
r46185 make_dirstate_tuple(py, &entry)?,
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 )?;
}
Ok(PyBytes::new(py, &packed))
}
Simon Sapin
rust: Replace DirstatePackError with HgError...
r47168 Err(error) => {
Err(PyErr::new::<exc::ValueError, _>(py, error.to_string()))
}
Raphaël Gomès
rust-parsers: move parser bindings to their own file and Python module...
r42992 }
}
/// Create the module, with `__package__` given from parent
pub fn init_parsers_module(py: Python, package: &str) -> PyResult<PyModule> {
let dotted_name = &format!("{}.parsers", package);
let m = PyModule::new(py, dotted_name)?;
m.add(py, "__package__", package)?;
m.add(py, "__doc__", "Parsers - Rust implementation")?;
m.add(
py,
"parse_dirstate",
py_fn!(
py,
parse_dirstate_wrapper(dmap: PyDict, copymap: PyDict, st: PyBytes)
),
)?;
m.add(
py,
"pack_dirstate",
py_fn!(
py,
pack_dirstate_wrapper(
dmap: PyDict,
copymap: PyDict,
pl: PyTuple,
now: PyInt
)
),
)?;
let sys = PyModule::import(py, "sys")?;
let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
sys_modules.set_item(py, dotted_name, &m)?;
Ok(m)
}