##// END OF EJS Templates
sidedatacopies: only fetch information once for merge...
sidedatacopies: only fetch information once for merge Before this change, merge would result in reading the data from revlog twice. With this change, we keep the information in memory until we encounter the other parent. When looking at pypy, I see about 1/3 of the changesets with copy information being merge. Not doing duplicated fetch for them provide a significant speedup. revision: large amount; added files: large amount; rename small amount; c3b14617fbd7 9ba6ab77fd29 before: ! wall 0.767042 comb 0.760000 user 0.750000 sys 0.010000 (median of 11) after: ! wall 0.671162 comb 0.670000 user 0.650000 sys 0.020000 (median of 13) revision: large amount; added files: small amount; rename small amount; c3b14617fbd7 f650a9b140d2 before: ! wall 1.170169 comb 1.170000 user 1.130000 sys 0.040000 (median of 10) after: ! wall 1.030596 comb 1.040000 user 1.010000 sys 0.030000 (median of 10) revision: large amount; added files: large amount; rename large amount; 08ea3258278e d9fa043f30c0 before: ! wall 0.209846 comb 0.200000 user 0.200000 sys 0.000000 (median of 46) after: ! wall 0.170981 comb 0.170000 user 0.170000 sys 0.000000 (median of 56) revision: small amount; added files: large amount; rename large amount; df6f7a526b60 a83dc6a2d56f before: ! wall 0.013248 comb 0.010000 user 0.010000 sys 0.000000 (median of 223) after: ! wall 0.013295 comb 0.020000 user 0.020000 sys 0.000000 (median of 222) revision: small amount; added files: large amount; rename small amount; 4aa4e1f8e19a 169138063d63 before: ! wall 0.001672 comb 0.000000 user 0.000000 sys 0.000000 (median of 1000) after: ! wall 0.001666 comb 0.000000 user 0.000000 sys 0.000000 (median of 1000) revision: small amount; added files: small amount; rename small amount; 4bc173b045a6 964879152e2e before: ! wall 0.000119 comb 0.000000 user 0.000000 sys 0.000000 (median of 8010) after: ! wall 0.000119 comb 0.000000 user 0.000000 sys 0.000000 (median of 8007) revision: medium amount; added files: large amount; rename medium amount; c95f1ced15f2 2c68e87c3efe before: ! wall 0.168599 comb 0.160000 user 0.160000 sys 0.000000 (median of 58) after: ! wall 0.133316 comb 0.140000 user 0.140000 sys 0.000000 (median of 73) revision: medium amount; added files: medium amount; rename small amount; d343da0c55a8 d7746d32bf9d before: ! wall 0.036052 comb 0.030000 user 0.030000 sys 0.000000 (median of 100) after: ! wall 0.032558 comb 0.030000 user 0.030000 sys 0.000000 (median of 100) Differential Revision: https://phab.mercurial-scm.org/D7127

File last commit:

r43227:7a01778b default
r43595:90213d02 default
Show More
filepatterns.rs
137 lines | 4.3 KiB | application/rls-services+xml | RustLexer
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 // filepatterns.rs
//
// Copyright 2019, Georges Racinet <gracinet@anybox.fr>,
// 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::filepatterns` module provided by the
//! `hg-core` crate. From Python, this will be seen as `rustext.filepatterns`
Yuya Nishihara
rust: apply more formatting fixes...
r43109 //! and can be used as replacement for the the pure `filepatterns` Python
//! module.
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 //!
Raphaël Gomès
rust: switch hg-core and hg-cpython to rust 2018 edition...
r42828 use crate::exceptions::{PatternError, PatternFileError};
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 use cpython::{
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 PyBytes, PyDict, PyModule, PyObject, PyResult, PyString, PyTuple, Python,
ToPyObject,
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 };
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 use hg::{
build_single_regex, read_pattern_file, utils::files::get_path_from_bytes,
LineNumber, PatternTuple,
};
use std::path::PathBuf;
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515
/// Rust does not like functions with different return signatures.
/// The 3-tuple version is always returned by the hg-core function,
/// the (potential) conversion is handled at this level since it is not likely
/// to have any measurable impact on performance.
///
/// The Python implementation passes a function reference for `warn` instead
/// of a boolean that is used to emit warnings while parsing. The Rust
/// implementation chooses to accumulate the warnings and propagate them to
/// Python upon completion. See the `readpatternfile` function in `match.py`
/// for more details.
fn read_pattern_file_wrapper(
py: Python,
Raphaël Gomès
rust-filepatterns: use bytes instead of String...
r42630 file_path: PyObject,
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 warn: bool,
source_info: bool,
) -> PyResult<PyTuple> {
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 let bytes = file_path.extract::<PyBytes>(py)?;
let path = get_path_from_bytes(bytes.data(py));
match read_pattern_file(path, warn) {
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 Ok((patterns, warnings)) => {
if source_info {
Raphaël Gomès
rust-filepatterns: use bytes instead of String...
r42630 let itemgetter = |x: &PatternTuple| {
(PyBytes::new(py, &x.0), x.1, PyBytes::new(py, &x.2))
};
let results: Vec<(PyBytes, LineNumber, PyBytes)> =
patterns.iter().map(itemgetter).collect();
Yuya Nishihara
rust-filepatterns: fix type of warnings tuple to (bytes, bytes)...
r42857 return Ok((results, warnings_to_py_bytes(py, &warnings))
.to_py_object(py));
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 }
Raphaël Gomès
rust-filepatterns: use bytes instead of String...
r42630 let itemgetter = |x: &PatternTuple| PyBytes::new(py, &x.0);
let results: Vec<PyBytes> =
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 patterns.iter().map(itemgetter).collect();
Yuya Nishihara
rust-filepatterns: fix type of warnings tuple to (bytes, bytes)...
r42857 Ok(
(results, warnings_to_py_bytes(py, &warnings))
.to_py_object(py),
)
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 }
Err(e) => Err(PatternFileError::pynew(py, e)),
}
}
Yuya Nishihara
rust-filepatterns: fix type of warnings tuple to (bytes, bytes)...
r42857 fn warnings_to_py_bytes(
py: Python,
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 warnings: &[(PathBuf, Vec<u8>)],
) -> Vec<(PyString, PyBytes)> {
Yuya Nishihara
rust-filepatterns: fix type of warnings tuple to (bytes, bytes)...
r42857 warnings
.iter()
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 .map(|(path, syn)| {
(
PyString::new(py, &path.to_string_lossy()),
PyBytes::new(py, syn),
)
})
Yuya Nishihara
rust-filepatterns: fix type of warnings tuple to (bytes, bytes)...
r42857 .collect()
}
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 fn build_single_regex_wrapper(
py: Python,
Raphaël Gomès
rust-filepatterns: use bytes instead of String...
r42630 kind: PyObject,
pat: PyObject,
globsuffix: PyObject,
) -> PyResult<PyBytes> {
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 match build_single_regex(
Raphaël Gomès
rust-filepatterns: use bytes instead of String...
r42630 kind.extract::<PyBytes>(py)?.data(py),
pat.extract::<PyBytes>(py)?.data(py),
globsuffix.extract::<PyBytes>(py)?.data(py),
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 ) {
Raphaël Gomès
rust-filepatterns: use bytes instead of String...
r42630 Ok(regex) => Ok(PyBytes::new(py, &regex)),
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 Err(e) => Err(PatternError::pynew(py, e)),
}
}
pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
let dotted_name = &format!("{}.filepatterns", package);
let m = PyModule::new(py, dotted_name)?;
m.add(py, "__package__", package)?;
m.add(
py,
"__doc__",
"Patterns files parsing - Rust implementation",
)?;
m.add(
py,
"build_single_regex",
py_fn!(
py,
build_single_regex_wrapper(
Raphaël Gomès
rust-filepatterns: use bytes instead of String...
r42630 kind: PyObject,
pat: PyObject,
globsuffix: PyObject
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 )
),
)?;
m.add(
py,
"read_pattern_file",
py_fn!(
py,
read_pattern_file_wrapper(
Raphaël Gomès
rust-filepatterns: use bytes instead of String...
r42630 file_path: PyObject,
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 warn: bool,
source_info: bool
)
),
)?;
Raphaël Gomès
rust-filepatterns: use bytes instead of String...
r42630 m.add(py, "PatternError", py.get_type::<PatternError>())?;
Raphaël Gomès
rust-filepatterns: add `rust-cpython` bindings for `filepatterns`...
r42515 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)
}