rust/hg-pyo3/src/dagops.rs
author Pierre-Yves David <pierre-yves.david@octobus.net>
Tue, 11 Mar 2025 02:29:42 +0100
branchstable
changeset 53042 cdd7bf612c7b
parent 52975 0db5f7987b13
permissions -rw-r--r--
bundle-spec: properly format boolean parameter (issue6960) This was breaking automatic clone bundle generation. This changeset fixes it and add a test to catch it in the future.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52407
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     1
// dagops.rs
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     2
//
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     3
// Copyright 2024 Georges Racinet <georges.racinet@cloudcrane.io>
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     4
//
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     7
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     8
//! Bindings for the `hg::dagops` module provided by the
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     9
//! `hg-core` package.
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    10
//!
52975
0db5f7987b13 rust-dagops: fix typo in docstring
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52841
diff changeset
    11
//! From Python, this will be seen as `mercurial.pyo3_rustext.dagop`
52407
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    12
use pyo3::prelude::*;
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    13
52413
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    14
use std::collections::HashSet;
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    15
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    16
use hg::{dagops, Revision};
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    17
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    18
use crate::exceptions::GraphError;
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    19
use crate::revision::{rev_pyiter_collect, PyRevision};
52841
28f0f00b5dbd rust-pyo3: rename the `util` file to `utils`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52838
diff changeset
    20
use crate::utils::{new_submodule, proxy_index_extract};
52407
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    21
52413
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    22
/// Using the the `index_proxy`, return heads out of any Python iterable of
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    23
/// Revisions
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    24
///
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    25
/// This is the Rust counterpart for `mercurial.dagop.headrevs`
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    26
#[pyfunction]
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    27
pub fn headrevs(
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    28
    index_proxy: &Bound<'_, PyAny>,
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    29
    revs: &Bound<'_, PyAny>,
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    30
) -> PyResult<HashSet<PyRevision>> {
52838
e52dc683bf6b rust-pyo3: switch over to the pyo3 `InnerRevlog`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52414
diff changeset
    31
    // Safety: we don't leak the "faked" reference out of `SharedByPyObject`
52414
233707101dae rust-pyo3: simplified API to get core Index references
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52413
diff changeset
    32
    let index = unsafe { proxy_index_extract(index_proxy)? };
52413
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    33
    let mut as_set: HashSet<Revision> = rev_pyiter_collect(revs, index)?;
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    34
    dagops::retain_heads(index, &mut as_set).map_err(GraphError::from_hg)?;
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    35
    Ok(as_set.into_iter().map(Into::into).collect())
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    36
}
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    37
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    38
/// Computes the rank, i.e. the number of ancestors including itself,
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    39
/// of a node represented by its parents.
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    40
///
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    41
/// Currently, the pure Rust index supports only the REVLOGV1 format, hence
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    42
/// the only possible return value is that the rank is unknown.
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    43
///
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    44
/// References:
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    45
/// - C implementation, function `index_fast_rank()`.
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    46
/// - `impl vcsgraph::graph::RankedGraph for Index` in `crate::cindex`.
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    47
#[pyfunction]
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    48
pub fn rank(
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    49
    _index: &Bound<'_, PyAny>,
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    50
    _p1r: PyRevision,
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    51
    _p2r: PyRevision,
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    52
) -> PyResult<()> {
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    53
    Err(GraphError::from_vcsgraph(
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    54
        vcsgraph::graph::GraphReadError::InconsistentGraphData,
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    55
    ))
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    56
}
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    57
52407
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    58
pub fn init_module<'py>(
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    59
    py: Python<'py>,
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    60
    package: &str,
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    61
) -> PyResult<Bound<'py, PyModule>> {
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    62
    let m = new_submodule(py, package, "dagop")?;
52413
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    63
    m.add_function(wrap_pyfunction!(headrevs, &m)?)?;
20fe0bf9a9a5 rust-pyo3: dagop submodule implementation
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    64
    m.add_function(wrap_pyfunction!(rank, &m)?)?;
52407
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    65
    Ok(m)
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    66
}