author | Raphaël Gomès <rgomes@octobus.net> |
Tue, 12 Apr 2022 17:27:56 +0200 | |
changeset 49137 | 66e22a4d856b |
parent 48853 | 4346be456875 |
child 50975 | 3aca98a35727 |
permissions | -rw-r--r-- |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
1 |
// cindex.rs |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
2 |
// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
3 |
// Copyright 2018 Georges Racinet <gracinet@anybox.fr> |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
4 |
// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
5 |
// This software may be used and distributed according to the terms of the |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
6 |
// GNU General Public License version 2 or any later version. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
7 |
|
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
8 |
//! Bindings to use the Index defined by the parsers C extension |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
9 |
//! |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
10 |
//! Ideally, we should use an Index entirely implemented in Rust, |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
11 |
//! but this will take some time to get there. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
12 |
|
44504
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
13 |
use cpython::{ |
47268
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
14 |
exc::ImportError, exc::TypeError, ObjectProtocol, PyClone, PyErr, |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
15 |
PyObject, PyResult, PyTuple, Python, PythonObject, |
44504
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
16 |
}; |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
17 |
use hg::revlog::{Node, RevlogIndex}; |
41350
ab0d762d89ef
rust-cpython: raising error.WdirUnsupported
Georges Racinet <georges.racinet@octobus.net>
parents:
41054
diff
changeset
|
18 |
use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION}; |
46412
7d0405e458a0
persistent-nodemap: Fix Rust declarations for Revlog_CAPI signatures
Simon Sapin <simon.sapin@octobus.net>
parents:
44973
diff
changeset
|
19 |
use libc::{c_int, ssize_t}; |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
20 |
|
48852
e633e660158f
revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents:
48518
diff
changeset
|
21 |
const REVLOG_CABI_VERSION: c_int = 3; |
44066
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
22 |
|
43959
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
23 |
#[repr(C)] |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
24 |
pub struct Revlog_CAPI { |
44066
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
25 |
abi_version: c_int, |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
26 |
index_length: |
46412
7d0405e458a0
persistent-nodemap: Fix Rust declarations for Revlog_CAPI signatures
Simon Sapin <simon.sapin@octobus.net>
parents:
44973
diff
changeset
|
27 |
unsafe extern "C" fn(index: *mut revlog_capi::RawPyObject) -> ssize_t, |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
28 |
index_node: unsafe extern "C" fn( |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
29 |
index: *mut revlog_capi::RawPyObject, |
46412
7d0405e458a0
persistent-nodemap: Fix Rust declarations for Revlog_CAPI signatures
Simon Sapin <simon.sapin@octobus.net>
parents:
44973
diff
changeset
|
30 |
rev: ssize_t, |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
31 |
) -> *const Node, |
48852
e633e660158f
revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents:
48518
diff
changeset
|
32 |
fast_rank: unsafe extern "C" fn( |
e633e660158f
revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents:
48518
diff
changeset
|
33 |
index: *mut revlog_capi::RawPyObject, |
e633e660158f
revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents:
48518
diff
changeset
|
34 |
rev: ssize_t, |
e633e660158f
revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents:
48518
diff
changeset
|
35 |
) -> ssize_t, |
43959
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
36 |
index_parents: unsafe extern "C" fn( |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
37 |
index: *mut revlog_capi::RawPyObject, |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
38 |
rev: c_int, |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
39 |
ps: *mut [c_int; 2], |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
40 |
) -> c_int, |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
41 |
} |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
42 |
|
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
43 |
py_capsule!( |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
44 |
from mercurial.cext.parsers import revlog_CAPI |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
45 |
as revlog_capi for Revlog_CAPI); |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
46 |
|
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
47 |
/// A `Graph` backed up by objects and functions from revlog.c |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
48 |
/// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
49 |
/// This implementation of the `Graph` trait, relies on (pointers to) |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
50 |
/// - the C index object (`index` member) |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
51 |
/// - the `index_get_parents()` function (`parents` member) |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
52 |
/// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
53 |
/// # Safety |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
54 |
/// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
55 |
/// The C index itself is mutable, and this Rust exposition is **not |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
56 |
/// protected by the GIL**, meaning that this construct isn't safe with respect |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
57 |
/// to Python threads. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
58 |
/// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
59 |
/// All callers of this `Index` must acquire the GIL and must not release it |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
60 |
/// while working. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
61 |
/// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
62 |
/// # TODO find a solution to make it GIL safe again. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
63 |
/// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
64 |
/// This is non trivial, and can wait until we have a clearer picture with |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
65 |
/// more Rust Mercurial constructs. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
66 |
/// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
67 |
/// One possibility would be to a `GILProtectedIndex` wrapper enclosing |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
68 |
/// a `Python<'p>` marker and have it be the one implementing the |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
69 |
/// `Graph` trait, but this would mean the `Graph` implementor would become |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
70 |
/// likely to change between subsequent method invocations of the `hg-core` |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
71 |
/// objects (a serious change of the `hg-core` API): |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
72 |
/// either exposing ways to mutate the `Graph`, or making it a non persistent |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
73 |
/// parameter in the relevant methods that need one. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
74 |
/// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
75 |
/// Another possibility would be to introduce an abstract lock handle into |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
76 |
/// the core API, that would be tied to `GILGuard` / `Python<'p>` |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
77 |
/// in the case of the `cpython` crate bindings yet could leave room for other |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
78 |
/// mechanisms in other contexts. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
79 |
pub struct Index { |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
80 |
index: PyObject, |
43959
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
81 |
capi: &'static Revlog_CAPI, |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
82 |
} |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
83 |
|
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
84 |
impl Index { |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
85 |
pub fn new(py: Python, index: PyObject) -> PyResult<Self> { |
44066
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
86 |
let capi = unsafe { revlog_capi::retrieve(py)? }; |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
87 |
if capi.abi_version != REVLOG_CABI_VERSION { |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
88 |
return Err(PyErr::new::<ImportError, _>( |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
89 |
py, |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
90 |
format!( |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
91 |
"ABI version mismatch: the C ABI revlog version {} \ |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
92 |
does not match the {} expected by Rust hg-cpython", |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
93 |
capi.abi_version, REVLOG_CABI_VERSION |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
94 |
), |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
95 |
)); |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
96 |
} |
47268
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
97 |
let compat: u64 = index.getattr(py, "rust_ext_compat")?.extract(py)?; |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
98 |
if compat == 0 { |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
99 |
return Err(PyErr::new::<TypeError, _>( |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
100 |
py, |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
101 |
"index object not compatible with Rust", |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
102 |
)); |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
103 |
} |
44973
26114bd6ec60
rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents:
44504
diff
changeset
|
104 |
Ok(Index { index, capi }) |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
105 |
} |
43960
ab3fd8077f5e
rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents:
43959
diff
changeset
|
106 |
|
ab3fd8077f5e
rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents:
43959
diff
changeset
|
107 |
/// return a reference to the CPython Index object in this Struct |
ab3fd8077f5e
rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents:
43959
diff
changeset
|
108 |
pub fn inner(&self) -> &PyObject { |
ab3fd8077f5e
rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents:
43959
diff
changeset
|
109 |
&self.index |
ab3fd8077f5e
rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents:
43959
diff
changeset
|
110 |
} |
44504
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
111 |
|
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
112 |
pub fn append(&mut self, py: Python, tup: PyTuple) -> PyResult<PyObject> { |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
113 |
self.index.call_method( |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
114 |
py, |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
115 |
"append", |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
116 |
PyTuple::new(py, &[tup.into_object()]), |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
117 |
None, |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
118 |
) |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
119 |
} |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
120 |
} |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
121 |
|
41054
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
122 |
impl Clone for Index { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
123 |
fn clone(&self) -> Self { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
124 |
let guard = Python::acquire_gil(); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
125 |
Index { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
126 |
index: self.index.clone_ref(guard.python()), |
43959
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
127 |
capi: self.capi, |
41054
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
128 |
} |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
129 |
} |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
130 |
} |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
131 |
|
44010
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
132 |
impl PyClone for Index { |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
133 |
fn clone_ref(&self, py: Python) -> Self { |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
134 |
Index { |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
135 |
index: self.index.clone_ref(py), |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
136 |
capi: self.capi, |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
137 |
} |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
138 |
} |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
139 |
} |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
140 |
|
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
141 |
impl Graph for Index { |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
142 |
/// wrap a call to the C extern parents function |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
143 |
fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { |
41350
ab0d762d89ef
rust-cpython: raising error.WdirUnsupported
Georges Racinet <georges.racinet@octobus.net>
parents:
41054
diff
changeset
|
144 |
if rev == WORKING_DIRECTORY_REVISION { |
ab0d762d89ef
rust-cpython: raising error.WdirUnsupported
Georges Racinet <georges.racinet@octobus.net>
parents:
41054
diff
changeset
|
145 |
return Err(GraphError::WorkingDirectoryUnsupported); |
ab0d762d89ef
rust-cpython: raising error.WdirUnsupported
Georges Racinet <georges.racinet@octobus.net>
parents:
41054
diff
changeset
|
146 |
} |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
147 |
let mut res: [c_int; 2] = [0; 2]; |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
148 |
let code = unsafe { |
43959
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
149 |
(self.capi.index_parents)( |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
150 |
self.index.as_ptr(), |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
151 |
rev as c_int, |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
152 |
&mut res as *mut [c_int; 2], |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
153 |
) |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
154 |
}; |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
155 |
match code { |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
156 |
0 => Ok(res), |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
157 |
_ => Err(GraphError::ParentOutOfRange(rev)), |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
158 |
} |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
159 |
} |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
160 |
} |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
161 |
|
48518
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
162 |
impl vcsgraph::graph::Graph for Index { |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
163 |
fn parents( |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
164 |
&self, |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
165 |
rev: Revision, |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
166 |
) -> Result<vcsgraph::graph::Parents, vcsgraph::graph::GraphReadError> |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
167 |
{ |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
168 |
match Graph::parents(self, rev) { |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
169 |
Ok(parents) => Ok(vcsgraph::graph::Parents(parents)), |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
170 |
Err(GraphError::ParentOutOfRange(rev)) => { |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
171 |
Err(vcsgraph::graph::GraphReadError::KeyedInvalidKey(rev)) |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
172 |
} |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
173 |
Err(GraphError::WorkingDirectoryUnsupported) => Err( |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
174 |
vcsgraph::graph::GraphReadError::WorkingDirectoryUnsupported, |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
175 |
), |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
176 |
} |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
177 |
} |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
178 |
} |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
179 |
|
48853
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
180 |
impl vcsgraph::graph::RankedGraph for Index { |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
181 |
fn rank( |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
182 |
&self, |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
183 |
rev: Revision, |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
184 |
) -> Result<vcsgraph::graph::Rank, vcsgraph::graph::GraphReadError> { |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
185 |
match unsafe { |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
186 |
(self.capi.fast_rank)(self.index.as_ptr(), rev as ssize_t) |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
187 |
} { |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
188 |
-1 => Err(vcsgraph::graph::GraphReadError::InconsistentGraphData), |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
189 |
rank => Ok(rank as usize), |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
190 |
} |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
191 |
} |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
192 |
} |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
193 |
|
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
194 |
impl RevlogIndex for Index { |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
195 |
/// Note C return type is Py_ssize_t (hence signed), but we shall |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
196 |
/// force it to unsigned, because it's a length |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
197 |
fn len(&self) -> usize { |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
198 |
unsafe { (self.capi.index_length)(self.index.as_ptr()) as usize } |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
199 |
} |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
200 |
|
44973
26114bd6ec60
rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents:
44504
diff
changeset
|
201 |
fn node(&self, rev: Revision) -> Option<&Node> { |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
202 |
let raw = unsafe { |
46412
7d0405e458a0
persistent-nodemap: Fix Rust declarations for Revlog_CAPI signatures
Simon Sapin <simon.sapin@octobus.net>
parents:
44973
diff
changeset
|
203 |
(self.capi.index_node)(self.index.as_ptr(), rev as ssize_t) |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
204 |
}; |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
205 |
if raw.is_null() { |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
206 |
None |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
207 |
} else { |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
208 |
// TODO it would be much better for the C layer to give us |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
209 |
// a length, since the hash length will change in the near |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
210 |
// future, but that's probably out of scope for the nodemap |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
211 |
// patch series. |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
212 |
// |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
213 |
// The root of that unsafety relies in the signature of |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
214 |
// `capi.index_node()` itself: returning a `Node` pointer |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
215 |
// whereas it's a `char *` in the C counterpart. |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
216 |
Some(unsafe { &*raw }) |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
217 |
} |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
218 |
} |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
219 |
} |