##// END OF EJS Templates
dirstate-tree: Use HashMap instead of BTreeMap...
dirstate-tree: Use HashMap instead of BTreeMap BTreeMap has the advantage of its "natural" iteration order being the one we need in the status algorithm. With HashMap however, iteration order is undefined so we need to allocate a Vec and sort it explicitly. Unfortunately many BTreeMap operations are slower than in HashMap, and skipping that extra allocation and sort is not enough to compensate. Switching to HashMap + sort makes `hg status` 17% faster in one test case, as measure with hyperfine: ``` Benchmark #1: ../hg2/hg status -R $REPO --config=experimental.dirstate-tree.in-memory=1 Time (mean ± σ): 765.0 ms ± 8.8 ms [User: 1.352 s, System: 0.747 s] Range (min … max): 751.8 ms … 778.7 ms 10 runs Benchmark #2: ./hg status -R $REPO --config=experimental.dirstate-tree.in-memory=1 Time (mean ± σ): 651.8 ms ± 9.9 ms [User: 1.251 s, System: 0.799 s] Range (min … max): 642.2 ms … 671.8 ms 10 runs Summary './hg status -R $REPO --config=experimental.dirstate-tree.in-memory=1' ran 1.17 ± 0.02 times faster than '../hg2/hg status -R $REPO --config=experimental.dirstate-tree.in-memory=1' ``` * ./hg is this revision * ../hg2/hg is its parent * $REPO is an old snapshot of mozilla-central Differential Revision: https://phab.mercurial-scm.org/D10553

File last commit:

r44398:f98f0e3d default
r47889:15395fd8 default
Show More
dagops.rs
53 lines | 1.8 KiB | application/rls-services+xml | RustLexer
Georges Racinet
rust-cpython: binding for headrevs()...
r41843 // dagops.rs
//
// Copyright 2019 Georges Racinet <georges.racinet@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::dagops` module provided by the
//! `hg-core` package.
//!
//! From Python, this will be seen as `mercurial.rustext.dagop`
rust-index: add a function to convert PyObject index for hg-core...
r44398 use crate::{conversion::rev_pyiter_collect, exceptions::GraphError};
Georges Racinet
rust-cpython: binding for headrevs()...
r41843 use cpython::{PyDict, PyModule, PyObject, PyResult, Python};
use hg::dagops;
use hg::Revision;
use std::collections::HashSet;
rust-index: add a function to convert PyObject index for hg-core...
r44398 use crate::revlog::pyindex_to_graph;
Georges Racinet
rust-cpython: binding for headrevs()...
r41843 /// Using the the `index`, return heads out of any Python iterable of Revisions
///
/// This is the Rust counterpart for `mercurial.dagop.headrevs`
pub fn headrevs(
py: Python,
index: PyObject,
revs: PyObject,
Georges Racinet
rust-cpython: removed now useless py_set() conversion...
r43563 ) -> PyResult<HashSet<Revision>> {
Georges Racinet
rust-cpython: binding for headrevs()...
r41843 let mut as_set: HashSet<Revision> = rev_pyiter_collect(py, &revs)?;
rust-index: add a function to convert PyObject index for hg-core...
r44398 dagops::retain_heads(&pyindex_to_graph(py, index)?, &mut as_set)
Georges Racinet
rust-cpython: binding for headrevs()...
r41843 .map_err(|e| GraphError::pynew(py, e))?;
Georges Racinet
rust-cpython: removed now useless py_set() conversion...
r43563 Ok(as_set)
Georges Racinet
rust-cpython: binding for headrevs()...
r41843 }
/// Create the module, with `__package__` given from parent
pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
let dotted_name = &format!("{}.dagop", package);
let m = PyModule::new(py, dotted_name)?;
m.add(py, "__package__", package)?;
m.add(py, "__doc__", "DAG operations - Rust implementation")?;
m.add(
py,
"headrevs",
py_fn!(py, headrevs(index: PyObject, revs: PyObject)),
)?;
let sys = PyModule::import(py, "sys")?;
let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
sys_modules.set_item(py, dotted_name, &m)?;
// Example C code (see pyexpat.c and import.c) will "give away the
// reference", but we won't because it will be consumed once the
// Rust PyObject is dropped.
Ok(m)
}