rust/hg-pyo3/src/ancestors.rs
author Pierre-Yves David <pierre-yves.david@octobus.net>
Thu, 02 Jan 2025 14:50:06 +0100
changeset 52592 87ceb51d124c
parent 52535 507fec66014f
child 52838 e52dc683bf6b
permissions -rw-r--r--
run-tests: drop jython support I don't think we heard anything about jython support for the past 15 years, so let's drop special support for it in run-tests.py it is most probably broken at that point.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52531
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     1
// ancestors.rs
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     2
//
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     3
// Copyright 2024 Georges Racinet <georges.racinet@cloudcrane.io>
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     4
//
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     7
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     8
//! Bindings for the `hg::ancestors` module provided by the
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     9
//! `hg-core` crate. From Python, this will be seen as `pyo3_rustext.ancestor`
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    10
//! and can be used as replacement for the the pure `ancestor` Python module.
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    11
use cpython::UnsafePyLeaked;
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    12
use pyo3::prelude::*;
52535
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
    13
use pyo3::types::PyTuple;
52531
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    14
52535
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
    15
use std::collections::HashSet;
52531
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    16
use std::sync::RwLock;
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    17
52535
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
    18
use hg::MissingAncestors as CoreMissing;
52533
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    19
use vcsgraph::lazy_ancestors::{
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    20
    AncestorsIterator as VCGAncestorsIterator,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    21
    LazyAncestors as VCGLazyAncestors,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    22
};
52531
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    23
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    24
use crate::convert_cpython::{
52534
9af0330788a5 rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52533
diff changeset
    25
    proxy_index_py_leak, py_leaked_borrow, py_leaked_borrow_mut,
9af0330788a5 rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52533
diff changeset
    26
    py_leaked_or_map_err,
52531
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    27
};
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    28
use crate::exceptions::{map_lock_error, GraphError};
52534
9af0330788a5 rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52533
diff changeset
    29
use crate::revision::{rev_pyiter_collect_with_py_index, PyRevision};
52531
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    30
use crate::util::new_submodule;
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    31
use rusthg::revlog::PySharedIndex;
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    32
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    33
#[pyclass]
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    34
struct AncestorsIterator {
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    35
    inner: RwLock<UnsafePyLeaked<VCGAncestorsIterator<PySharedIndex>>>,
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    36
}
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    37
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    38
#[pymethods]
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    39
impl AncestorsIterator {
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    40
    #[new]
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    41
    fn new(
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    42
        index_proxy: &Bound<'_, PyAny>,
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    43
        initrevs: &Bound<'_, PyAny>,
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    44
        stoprev: PyRevision,
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    45
        inclusive: bool,
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    46
    ) -> PyResult<Self> {
52534
9af0330788a5 rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52533
diff changeset
    47
        let initvec: Vec<_> =
9af0330788a5 rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52533
diff changeset
    48
            rev_pyiter_collect_with_py_index(initrevs, index_proxy)?;
52531
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    49
        let (py, leaked_idx) = proxy_index_py_leak(index_proxy)?;
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    50
        let res_ait = unsafe {
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    51
            leaked_idx.map(py, |idx| {
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    52
                VCGAncestorsIterator::new(
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    53
                    idx,
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    54
                    initvec.into_iter().map(|r| r.0),
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    55
                    stoprev.0,
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    56
                    inclusive,
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    57
                )
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    58
            })
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    59
        };
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    60
        let ait =
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    61
            py_leaked_or_map_err(py, res_ait, GraphError::from_vcsgraph)?;
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    62
        let inner = ait.into();
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    63
        Ok(Self { inner })
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    64
    }
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    65
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    66
    fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    67
        slf
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    68
    }
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    69
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    70
    fn __next__(slf: PyRefMut<'_, Self>) -> PyResult<Option<PyRevision>> {
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    71
        let mut leaked = slf.inner.write().map_err(map_lock_error)?;
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    72
        // Safety: we don't leak the inner 'static ref out of UnsafePyLeaked
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    73
        let mut inner = unsafe { py_leaked_borrow_mut(&slf, &mut leaked)? };
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    74
        match inner.next() {
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    75
            Some(Err(e)) => Err(GraphError::from_vcsgraph(e)),
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    76
            None => Ok(None),
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    77
            Some(Ok(r)) => Ok(Some(PyRevision(r))),
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    78
        }
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    79
    }
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    80
}
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    81
52533
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    82
#[pyclass(sequence)]
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    83
struct LazyAncestors {
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    84
    inner: RwLock<UnsafePyLeaked<VCGLazyAncestors<PySharedIndex>>>,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    85
    proxy_index: PyObject,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    86
    initrevs: PyObject,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    87
    stoprev: PyRevision,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    88
    inclusive: bool,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    89
}
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    90
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    91
#[pymethods]
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    92
impl LazyAncestors {
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    93
    #[new]
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    94
    fn new(
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    95
        index_proxy: &Bound<'_, PyAny>,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    96
        initrevs: &Bound<'_, PyAny>,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    97
        stoprev: PyRevision,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    98
        inclusive: bool,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
    99
    ) -> PyResult<Self> {
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   100
        let cloned_proxy = index_proxy.clone().unbind();
52534
9af0330788a5 rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52533
diff changeset
   101
        let initvec: Vec<_> =
9af0330788a5 rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52533
diff changeset
   102
            rev_pyiter_collect_with_py_index(initrevs, index_proxy)?;
52533
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   103
        let (py, leaked_idx) = proxy_index_py_leak(index_proxy)?;
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   104
        // Safety: we don't leak the "faked" reference out of
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   105
        // `UnsafePyLeaked`
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   106
        let res_lazy = unsafe {
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   107
            leaked_idx.map(py, |idx| {
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   108
                VCGLazyAncestors::new(
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   109
                    idx,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   110
                    initvec.into_iter().map(|r| r.0),
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   111
                    stoprev.0,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   112
                    inclusive,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   113
                )
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   114
            })
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   115
        };
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   116
        let lazy =
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   117
            py_leaked_or_map_err(py, res_lazy, GraphError::from_vcsgraph)?;
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   118
        Ok(Self {
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   119
            inner: lazy.into(),
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   120
            proxy_index: cloned_proxy,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   121
            initrevs: initrevs.clone().unbind(),
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   122
            stoprev,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   123
            inclusive,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   124
        })
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   125
    }
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   126
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   127
    fn __bool__(slf: PyRef<'_, Self>) -> PyResult<bool> {
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   128
        let leaked = slf.inner.read().map_err(map_lock_error)?;
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   129
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   130
        let inner = unsafe { py_leaked_borrow(&slf, &leaked) }?;
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   131
        Ok(!inner.is_empty())
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   132
    }
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   133
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   134
    fn __contains__(
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   135
        slf: PyRefMut<'_, Self>,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   136
        obj: &Bound<'_, PyAny>,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   137
    ) -> PyResult<bool> {
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   138
        PyRevision::extract_bound(obj).map_or(Ok(false), |rev| {
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   139
            let mut leaked = slf.inner.write().map_err(map_lock_error)?;
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   140
            // Safety: we don't leak the "faked" reference out of
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   141
            // `UnsafePyLeaked`
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   142
            let mut inner =
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   143
                unsafe { py_leaked_borrow_mut(&slf, &mut leaked) }?;
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   144
            inner.contains(rev.0).map_err(GraphError::from_vcsgraph)
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   145
        })
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   146
    }
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   147
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   148
    fn __iter__(slf: PyRef<'_, Self>) -> PyResult<AncestorsIterator> {
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   149
        let py = slf.py();
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   150
        AncestorsIterator::new(
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   151
            slf.proxy_index.clone_ref(py).bind(py),
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   152
            slf.initrevs.clone_ref(py).bind(py),
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   153
            slf.stoprev,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   154
            slf.inclusive,
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   155
        )
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   156
    }
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   157
}
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   158
52535
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   159
#[pyclass]
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   160
struct MissingAncestors {
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   161
    inner: RwLock<UnsafePyLeaked<CoreMissing<PySharedIndex>>>,
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   162
    proxy_index: PyObject,
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   163
}
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   164
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   165
#[pymethods]
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   166
impl MissingAncestors {
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   167
    #[new]
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   168
    fn new(
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   169
        index_proxy: &Bound<'_, PyAny>,
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   170
        bases: &Bound<'_, PyAny>,
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   171
    ) -> PyResult<Self> {
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   172
        let cloned_proxy = index_proxy.clone().unbind();
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   173
        let bases_vec: Vec<_> =
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   174
            rev_pyiter_collect_with_py_index(bases, index_proxy)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   175
        let (py, leaked_idx) = proxy_index_py_leak(index_proxy)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   176
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   177
        // Safety: we don't leak the "faked" reference out of
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   178
        // `UnsafePyLeaked`
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   179
        let inner = unsafe {
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   180
            leaked_idx.map(py, |idx| CoreMissing::new(idx, bases_vec))
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   181
        };
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   182
        Ok(Self {
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   183
            inner: inner.into(),
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   184
            proxy_index: cloned_proxy,
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   185
        })
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   186
    }
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   187
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   188
    fn hasbases(slf: PyRef<'_, Self>) -> PyResult<bool> {
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   189
        let leaked = slf.inner.read().map_err(map_lock_error)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   190
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   191
        let inner = unsafe { py_leaked_borrow(&slf, &leaked) }?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   192
        Ok(inner.has_bases())
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   193
    }
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   194
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   195
    fn addbases(
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   196
        slf: PyRefMut<'_, Self>,
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   197
        bases: &Bound<'_, PyAny>,
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   198
    ) -> PyResult<()> {
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   199
        let index_proxy = slf.proxy_index.bind(slf.py());
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   200
        let bases_vec: Vec<_> =
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   201
            rev_pyiter_collect_with_py_index(bases, index_proxy)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   202
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   203
        let mut leaked = slf.inner.write().map_err(map_lock_error)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   204
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   205
        let mut inner = unsafe { py_leaked_borrow_mut(&slf, &mut leaked) }?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   206
        inner.add_bases(bases_vec);
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   207
        Ok(())
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   208
    }
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   209
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   210
    fn bases(slf: PyRef<'_, Self>) -> PyResult<HashSet<PyRevision>> {
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   211
        let leaked = slf.inner.read().map_err(map_lock_error)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   212
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   213
        let inner = unsafe { py_leaked_borrow(&slf, &leaked) }?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   214
        Ok(inner.get_bases().iter().map(|r| PyRevision(r.0)).collect())
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   215
    }
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   216
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   217
    fn basesheads(slf: PyRef<'_, Self>) -> PyResult<HashSet<PyRevision>> {
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   218
        let leaked = slf.inner.read().map_err(map_lock_error)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   219
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   220
        let inner = unsafe { py_leaked_borrow(&slf, &leaked) }?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   221
        Ok(inner
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   222
            .bases_heads()
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   223
            .map_err(GraphError::from_hg)?
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   224
            .iter()
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   225
            .map(|r| PyRevision(r.0))
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   226
            .collect())
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   227
    }
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   228
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   229
    fn removeancestorsfrom(
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   230
        slf: PyRef<'_, Self>,
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   231
        revs: &Bound<'_, PyAny>,
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   232
    ) -> PyResult<()> {
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   233
        // Original comment from hg-cpython:
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   234
        //   this is very lame: we convert to a Rust set, update it in place
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   235
        //   and then convert back to Python, only to have Python remove the
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   236
        //   excess (thankfully, Python is happy with a list or even an
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   237
        //   iterator)
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   238
        //   Leads to improve this:
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   239
        //    - have the CoreMissing instead do something emit revisions to
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   240
        //      discard
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   241
        //    - define a trait for sets of revisions in the core and implement
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   242
        //      it for a Python set rewrapped with the GIL marker
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   243
        // PyO3 additional comment: the trait approach would probably be
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   244
        // simpler because we can implement it without a Py wrappper, just
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   245
        // on &Bound<'py, PySet>
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   246
        let index_proxy = slf.proxy_index.bind(slf.py());
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   247
        let mut revs_set: HashSet<_> =
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   248
            rev_pyiter_collect_with_py_index(revs, index_proxy)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   249
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   250
        let mut leaked = slf.inner.write().map_err(map_lock_error)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   251
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   252
        let mut inner = unsafe { py_leaked_borrow_mut(&slf, &mut leaked) }?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   253
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   254
        inner
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   255
            .remove_ancestors_from(&mut revs_set)
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   256
            .map_err(GraphError::from_hg)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   257
        // convert as Python tuple and discard from original `revs`
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   258
        let remaining_tuple =
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   259
            PyTuple::new(slf.py(), revs_set.iter().map(|r| PyRevision(r.0)))?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   260
        revs.call_method("intersection_update", (remaining_tuple,), None)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   261
        Ok(())
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   262
    }
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   263
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   264
    fn missingancestors(
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   265
        slf: PyRefMut<'_, Self>,
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   266
        bases: &Bound<'_, PyAny>,
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   267
    ) -> PyResult<Vec<PyRevision>> {
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   268
        let index_proxy = slf.proxy_index.bind(slf.py());
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   269
        let revs_vec: Vec<_> =
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   270
            rev_pyiter_collect_with_py_index(bases, index_proxy)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   271
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   272
        let mut leaked = slf.inner.write().map_err(map_lock_error)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   273
        // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   274
        let mut inner = unsafe { py_leaked_borrow_mut(&slf, &mut leaked) }?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   275
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   276
        let missing_vec = inner
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   277
            .missing_ancestors(revs_vec)
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   278
            .map_err(GraphError::from_hg)?;
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   279
        Ok(missing_vec.iter().map(|r| PyRevision(r.0)).collect())
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   280
    }
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   281
}
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   282
52531
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   283
pub fn init_module<'py>(
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   284
    py: Python<'py>,
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   285
    package: &str,
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   286
) -> PyResult<Bound<'py, PyModule>> {
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   287
    let m = new_submodule(py, package, "ancestor")?;
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   288
    m.add_class::<AncestorsIterator>()?;
52533
6b694bdf752a rust-pyo3: implementation of LazyAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52531
diff changeset
   289
    m.add_class::<LazyAncestors>()?;
52535
507fec66014f rust-pyo3: MissingAncestors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52534
diff changeset
   290
    m.add_class::<MissingAncestors>()?;
52531
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   291
    Ok(m)
4c9e31984b3a rust-pyo3: exposition of AncestorsIterator
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   292
}