rust/hg-cpython/src/discovery.rs
author Georges Racinet <georges.racinet@cloudcrane.io>
Sat, 30 Nov 2024 20:57:02 +0100
changeset 52411 c2480ac4c5e2
parent 51252 24d3298189d7
permissions -rw-r--r--
rust-pyo3: retrieving the InnerRevlog of hg-cpython This allows PyO3-based code to use the InnerRevlog, access its shared data (core InnerRevlog), which will then allow, e.g., to retrieve references on the core Index. On the `hg-cpython` (`rusthg` crate, `rustext` Python extension module), we had to also build as a Rust library, and open up some accesses (see notably the public accessor for `inner`, the core `InnerRevlog`). Retrieving the Rust struct underlying a Python object defined by another extension module written in Rust is tricky because the Python type objects are duplicated in the extension modules, leading to failure of the normal type checking. See the doc-comment of `convert_cpython::extract_inner_revlog` for a complete explanation. To solve this, we import the Python type object of `rustext` (defined by `hg-cpython`) and perform a manual check. Checking the Python type is necessary, as PyO3 documentation clearly state that downcasting an object that has not the proper type is Undefined Behaviour. At this point, we do not have conversion facilities for exceptions (`PyErr` on both sides), hence the remaining unwraps).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     1
// discovery.rs
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     2
//
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     3
// Copyright 2018 Georges Racinet <gracinet@anybox.fr>
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     4
//
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     7
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     8
//! Bindings for the `hg::discovery` module provided by the
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     9
//! `hg-core` crate. From Python, this will be seen as `rustext.discovery`
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    10
//!
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    11
//! # Classes visible from Python:
51182
a6e293b21743 rust: fix cargo doc for hg-cpython
Georges Racinet <georges.racinet@octobus.net>
parents: 50976
diff changeset
    12
//! - [`PartialDiscovery`] is the Rust implementation of
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    13
//!   `mercurial.setdiscovery.partialdiscovery`.
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    14
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43945
diff changeset
    15
use crate::PyRevision;
42609
326fdce22fb2 rust: switch hg-core and hg-cpython to rust 2018 edition
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42332
diff changeset
    16
use crate::{
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    17
    conversion::rev_pyiter_collect, exceptions::GraphError,
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    18
    revlog::PySharedIndex,
42609
326fdce22fb2 rust: switch hg-core and hg-cpython to rust 2018 edition
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42332
diff changeset
    19
};
42180
1b0be75cb61f rust-discovery: implementing and exposing stats()
Georges Racinet <georges.racinet@octobus.net>
parents: 42179
diff changeset
    20
use cpython::{
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43945
diff changeset
    21
    ObjectProtocol, PyClone, PyDict, PyModule, PyObject, PyResult, PyTuple,
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    22
    Python, PythonObject, ToPyObject, UnsafePyLeaked,
42180
1b0be75cb61f rust-discovery: implementing and exposing stats()
Georges Racinet <georges.racinet@octobus.net>
parents: 42179
diff changeset
    23
};
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    24
use hg::discovery::PartialDiscovery as CorePartialDiscovery;
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    25
use hg::Revision;
43269
33fe96a5c522 rust-cpython: removed now useless py_set() conversion
Georges Racinet <georges.racinet@octobus.net>
parents: 42741
diff changeset
    26
use std::collections::HashSet;
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    27
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    28
use std::cell::RefCell;
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    29
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    30
use crate::revlog::py_rust_index_to_graph;
43945
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43269
diff changeset
    31
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    32
py_class!(pub class PartialDiscovery |py| {
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    33
    data inner: RefCell<UnsafePyLeaked<CorePartialDiscovery<PySharedIndex>>>;
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    34
    data index: RefCell<UnsafePyLeaked<PySharedIndex>>;
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    35
42735
5154701a5413 rust-discovery: accept the new 'respectsize' init arg
Georges Racinet <georges.racinet@octobus.net>
parents: 42609
diff changeset
    36
    // `_respectsize` is currently only here to replicate the Python API and
5154701a5413 rust-discovery: accept the new 'respectsize' init arg
Georges Racinet <georges.racinet@octobus.net>
parents: 42609
diff changeset
    37
    // will be used in future patches inside methods that are yet to be
5154701a5413 rust-discovery: accept the new 'respectsize' init arg
Georges Racinet <georges.racinet@octobus.net>
parents: 42609
diff changeset
    38
    // implemented.
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    39
    def __new__(
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    40
        _cls,
42736
b6f3f704a561 rust-discovery: read the index from a repo passed at init
Georges Racinet <georges.racinet@octobus.net>
parents: 42735
diff changeset
    41
        repo: PyObject,
42735
5154701a5413 rust-discovery: accept the new 'respectsize' init arg
Georges Racinet <georges.racinet@octobus.net>
parents: 42609
diff changeset
    42
        targetheads: PyObject,
42741
4e7bd6180b53 rust-discovery: optionally don't randomize at all, for tests
Georges Racinet <georges.racinet@octobus.net>
parents: 42740
diff changeset
    43
        respectsize: bool,
4e7bd6180b53 rust-discovery: optionally don't randomize at all, for tests
Georges Racinet <georges.racinet@octobus.net>
parents: 42740
diff changeset
    44
        randomize: bool = true
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    45
    ) -> PyResult<PartialDiscovery> {
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
    46
        Self::inner_new(py, repo, targetheads, respectsize, randomize)
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    47
    }
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    48
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    49
    def addcommons(&self, commons: PyObject) -> PyResult<PyObject> {
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
    50
        self.inner_addcommons(py, commons)
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
    51
    }
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    52
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    53
    def addmissings(&self, missings: PyObject) -> PyResult<PyObject> {
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
    54
        self.inner_addmissings(py, missings)
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    55
    }
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    56
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    57
    def addinfo(&self, sample: PyObject) -> PyResult<PyObject> {
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
    58
        self.inner_addinfo(py, sample)
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    59
    }
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    60
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    61
    def hasinfo(&self) -> PyResult<bool> {
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    62
        let leaked = self.inner(py).borrow();
51252
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51242
diff changeset
    63
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    64
        let inner = unsafe { leaked.try_borrow(py)? };
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    65
        Ok(inner.has_info())
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    66
    }
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    67
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    68
    def iscomplete(&self) -> PyResult<bool> {
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    69
        let leaked = self.inner(py).borrow();
51252
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51242
diff changeset
    70
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    71
        let inner = unsafe { leaked.try_borrow(py)? };
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    72
        Ok(inner.is_complete())
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    73
    }
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    74
42180
1b0be75cb61f rust-discovery: implementing and exposing stats()
Georges Racinet <georges.racinet@octobus.net>
parents: 42179
diff changeset
    75
    def stats(&self) -> PyResult<PyDict> {
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    76
        let leaked = self.inner(py).borrow();
51252
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51242
diff changeset
    77
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    78
        let inner = unsafe { leaked.try_borrow(py)? };
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    79
        let stats = inner.stats();
42180
1b0be75cb61f rust-discovery: implementing and exposing stats()
Georges Racinet <georges.racinet@octobus.net>
parents: 42179
diff changeset
    80
        let as_dict: PyDict = PyDict::new(py);
1b0be75cb61f rust-discovery: implementing and exposing stats()
Georges Racinet <georges.racinet@octobus.net>
parents: 42179
diff changeset
    81
        as_dict.set_item(py, "undecided",
42332
163b8fd7bb72 rust-python3: compatibility fix for integer conversion
Georges Racinet <georges.racinet@octobus.net>
parents: 42180
diff changeset
    82
                         stats.undecided.map(
163b8fd7bb72 rust-python3: compatibility fix for integer conversion
Georges Racinet <georges.racinet@octobus.net>
parents: 42180
diff changeset
    83
                             |l| l.to_py_object(py).into_object())
163b8fd7bb72 rust-python3: compatibility fix for integer conversion
Georges Racinet <georges.racinet@octobus.net>
parents: 42180
diff changeset
    84
                             .unwrap_or_else(|| py.None()))?;
42180
1b0be75cb61f rust-discovery: implementing and exposing stats()
Georges Racinet <georges.racinet@octobus.net>
parents: 42179
diff changeset
    85
        Ok(as_dict)
1b0be75cb61f rust-discovery: implementing and exposing stats()
Georges Racinet <georges.racinet@octobus.net>
parents: 42179
diff changeset
    86
    }
1b0be75cb61f rust-discovery: implementing and exposing stats()
Georges Racinet <georges.racinet@octobus.net>
parents: 42179
diff changeset
    87
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43945
diff changeset
    88
    def commonheads(&self) -> PyResult<HashSet<PyRevision>> {
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    89
        let leaked = self.inner(py).borrow();
51252
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51242
diff changeset
    90
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    91
        let inner = unsafe { leaked.try_borrow(py)? };
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
    92
        let res = inner.common_heads()
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43945
diff changeset
    93
                    .map_err(|e| GraphError::pynew(py, e))?;
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43945
diff changeset
    94
        Ok(res.into_iter().map(Into::into).collect())
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    95
    }
42740
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
    96
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
    97
    def takefullsample(&self, headrevs: PyObject,
42740
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
    98
                       size: usize) -> PyResult<PyObject> {
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
    99
        self.inner_takefullsample(py, headrevs, size)
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   100
    }
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   101
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   102
    def takequicksample(&self, headrevs: PyObject,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   103
                        size: usize) -> PyResult<PyObject> {
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   104
        self.inner_takequicksample(py, headrevs, size)
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   105
    }
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   106
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   107
});
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   108
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   109
impl PartialDiscovery {
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   110
    fn inner_new(
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   111
        py: Python,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   112
        repo: PyObject,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   113
        targetheads: PyObject,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   114
        respectsize: bool,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   115
        randomize: bool,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   116
    ) -> PyResult<Self> {
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   117
        let index = repo.getattr(py, "changelog")?.getattr(py, "index")?;
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   118
        let cloned_index = py_rust_index_to_graph(py, index.clone_ref(py))?;
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   119
        let index = py_rust_index_to_graph(py, index)?;
51252
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51242
diff changeset
   120
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   121
        let target_heads = {
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   122
            let borrowed_idx = unsafe { index.try_borrow(py)? };
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   123
            rev_pyiter_collect(py, &targetheads, &*borrowed_idx)?
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   124
        };
51252
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51242
diff changeset
   125
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   126
        let lazy_disco = unsafe {
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   127
            index.map(py, |idx| {
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   128
                CorePartialDiscovery::new(
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   129
                    idx,
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   130
                    target_heads,
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   131
                    respectsize,
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   132
                    randomize,
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   133
                )
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   134
            })
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   135
        };
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   136
        Self::create_instance(
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   137
            py,
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   138
            RefCell::new(lazy_disco),
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   139
            RefCell::new(cloned_index),
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   140
        )
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   141
    }
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   142
51240
0993a3520dc6 rust-discovery: encapsulated conversions to vec for instance methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
   143
    /// Convert a Python iterator of revisions into a vector
0993a3520dc6 rust-discovery: encapsulated conversions to vec for instance methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
   144
    fn pyiter_to_vec(
0993a3520dc6 rust-discovery: encapsulated conversions to vec for instance methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
   145
        &self,
0993a3520dc6 rust-discovery: encapsulated conversions to vec for instance methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
   146
        py: Python,
0993a3520dc6 rust-discovery: encapsulated conversions to vec for instance methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
   147
        iter: &PyObject,
0993a3520dc6 rust-discovery: encapsulated conversions to vec for instance methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
   148
    ) -> PyResult<Vec<Revision>> {
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   149
        let leaked = self.index(py).borrow();
51252
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51242
diff changeset
   150
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   151
        let index = unsafe { leaked.try_borrow(py)? };
51240
0993a3520dc6 rust-discovery: encapsulated conversions to vec for instance methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
   152
        rev_pyiter_collect(py, iter, &*index)
0993a3520dc6 rust-discovery: encapsulated conversions to vec for instance methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
   153
    }
0993a3520dc6 rust-discovery: encapsulated conversions to vec for instance methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
   154
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   155
    fn inner_addinfo(
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   156
        &self,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   157
        py: Python,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   158
        sample: PyObject,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   159
    ) -> PyResult<PyObject> {
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   160
        let mut missing: Vec<Revision> = Vec::new();
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   161
        let mut common: Vec<Revision> = Vec::new();
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   162
        for info in sample.iter(py)? {
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   163
            // info is a pair (Revision, bool)
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   164
            let mut revknown = info?.iter(py)?;
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   165
            let rev: PyRevision = revknown.next().unwrap()?.extract(py)?;
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   166
            // This is fine since we're just using revisions as integers
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   167
            // for the purposes of discovery
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   168
            let rev = Revision(rev.0);
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   169
            let known: bool = revknown.next().unwrap()?.extract(py)?;
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   170
            if known {
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   171
                common.push(rev);
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   172
            } else {
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   173
                missing.push(rev);
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   174
            }
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   175
        }
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   176
        let mut leaked = self.inner(py).borrow_mut();
51252
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51242
diff changeset
   177
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   178
        let mut inner = unsafe { leaked.try_borrow_mut(py)? };
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   179
        inner
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   180
            .add_common_revisions(common)
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   181
            .map_err(|e| GraphError::pynew(py, e))?;
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   182
        inner
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   183
            .add_missing_revisions(missing)
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   184
            .map_err(|e| GraphError::pynew(py, e))?;
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   185
        Ok(py.None())
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   186
    }
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   187
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   188
    fn inner_addcommons(
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   189
        &self,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   190
        py: Python,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   191
        commons: PyObject,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   192
    ) -> PyResult<PyObject> {
51240
0993a3520dc6 rust-discovery: encapsulated conversions to vec for instance methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
   193
        let commons_vec = self.pyiter_to_vec(py, &commons)?;
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   194
        let mut leaked = self.inner(py).borrow_mut();
51252
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51242
diff changeset
   195
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   196
        let mut inner = unsafe { leaked.try_borrow_mut(py)? };
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   197
        inner
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   198
            .add_common_revisions(commons_vec)
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   199
            .map_err(|e| GraphError::pynew(py, e))?;
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   200
        Ok(py.None())
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   201
    }
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   202
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   203
    fn inner_addmissings(
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   204
        &self,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   205
        py: Python,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   206
        missings: PyObject,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   207
    ) -> PyResult<PyObject> {
51240
0993a3520dc6 rust-discovery: encapsulated conversions to vec for instance methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
   208
        let missings_vec = self.pyiter_to_vec(py, &missings)?;
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   209
        let mut leaked = self.inner(py).borrow_mut();
51252
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51242
diff changeset
   210
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   211
        let mut inner = unsafe { leaked.try_borrow_mut(py)? };
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   212
        inner
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   213
            .add_missing_revisions(missings_vec)
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   214
            .map_err(|e| GraphError::pynew(py, e))?;
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   215
        Ok(py.None())
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   216
    }
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   217
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   218
    fn inner_takefullsample(
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   219
        &self,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   220
        py: Python,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   221
        _headrevs: PyObject,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   222
        size: usize,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   223
    ) -> PyResult<PyObject> {
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   224
        let mut leaked = self.inner(py).borrow_mut();
51252
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51242
diff changeset
   225
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   226
        let mut inner = unsafe { leaked.try_borrow_mut(py)? };
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   227
        let sample = inner
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   228
            .take_full_sample(size)
42740
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
   229
            .map_err(|e| GraphError::pynew(py, e))?;
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
   230
        let as_vec: Vec<PyObject> = sample
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
   231
            .iter()
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43945
diff changeset
   232
            .map(|rev| PyRevision(rev.0).to_py_object(py).into_object())
42740
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
   233
            .collect();
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
   234
        Ok(PyTuple::new(py, as_vec.as_slice()).into_object())
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
   235
    }
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
   236
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   237
    fn inner_takequicksample(
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   238
        &self,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   239
        py: Python,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   240
        headrevs: PyObject,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   241
        size: usize,
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   242
    ) -> PyResult<PyObject> {
51240
0993a3520dc6 rust-discovery: encapsulated conversions to vec for instance methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
   243
        let revsvec = self.pyiter_to_vec(py, &headrevs)?;
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   244
        let mut leaked = self.inner(py).borrow_mut();
51252
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51242
diff changeset
   245
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51242
0b81440e2a73 rust-index: using `hg::index::Index` in discovery
Georges Racinet <georges.racinet@octobus.net>
parents: 51240
diff changeset
   246
        let mut inner = unsafe { leaked.try_borrow_mut(py)? };
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   247
        let sample = inner
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   248
            .take_quick_sample(revsvec, size)
42740
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
   249
            .map_err(|e| GraphError::pynew(py, e))?;
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
   250
        let as_vec: Vec<PyObject> = sample
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
   251
            .iter()
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43945
diff changeset
   252
            .map(|rev| PyRevision(rev.0).to_py_object(py).into_object())
42740
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
   253
            .collect();
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
   254
        Ok(PyTuple::new(py, as_vec.as_slice()).into_object())
1c4b5689bef5 rust-discovery: exposing sampling to python
Georges Racinet <georges.racinet@octobus.net>
parents: 42738
diff changeset
   255
    }
51239
2e2832e00f6c rust-discovery: moving most of hg-cpython methods to regular code blocks
Georges Racinet <georges.racinet@octobus.net>
parents: 51182
diff changeset
   256
}
42179
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   257
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   258
/// Create the module, with __package__ given from parent
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   259
pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   260
    let dotted_name = &format!("{}.discovery", package);
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   261
    let m = PyModule::new(py, dotted_name)?;
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   262
    m.add(py, "__package__", package)?;
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   263
    m.add(
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   264
        py,
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   265
        "__doc__",
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   266
        "Discovery of common node sets - Rust implementation",
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   267
    )?;
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   268
    m.add_class::<PartialDiscovery>(py)?;
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   269
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   270
    let sys = PyModule::import(py, "sys")?;
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   271
    let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   272
    sys_modules.set_item(py, dotted_name, &m)?;
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   273
    // Example C code (see pyexpat.c and import.c) will "give away the
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   274
    // reference", but we won't because it will be consumed once the
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   275
    // Rust PyObject is dropped.
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   276
    Ok(m)
13b64247f48f rust-discovery: cpython bindings for the core logic
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   277
}