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-- |
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 |
} |