annotate rust/hg-cpython/src/cindex.rs @ 44304:dbbae122f5e4

manifest: remove optional default= argument on flags(path) It had only one caller inside manifest.py, and treemanifest was actually incorrectly implemented. treemanifest is still missing the fastdelta() method from the interface (and so doesn't yet conform), but this is at least progress. Differential Revision: https://phab.mercurial-scm.org/D8069
author Augie Fackler <augie@google.com>
date Mon, 03 Feb 2020 22:16:36 -0500
parents f5d2720f3bea
children 166349510398
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
41055
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
44066
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
13 use cpython::{exc::ImportError, PyClone, PyErr, PyObject, PyResult, Python};
41310
ab0d762d89ef rust-cpython: raising error.WdirUnsupported
Georges Racinet <georges.racinet@octobus.net>
parents: 41057
diff changeset
14 use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION};
41055
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
15 use libc::c_int;
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
16
44066
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
17 const REVLOG_CABI_VERSION: c_int = 1;
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
18
43964
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
19 #[repr(C)]
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
20 pub struct Revlog_CAPI {
44066
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
21 abi_version: c_int,
43964
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
22 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
23 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
24 rev: c_int,
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
25 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
26 ) -> c_int,
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
27 }
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
28
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
29 py_capsule!(
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
30 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
31 as revlog_capi for Revlog_CAPI);
41055
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
32
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
33 /// 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
34 ///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
35 /// 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
36 /// - the C index object (`index` member)
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
37 /// - the `index_get_parents()` function (`parents` member)
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
38 ///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
39 /// # Safety
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
40 ///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
41 /// 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
42 /// 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
43 /// to Python threads.
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
44 ///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
45 /// 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
46 /// while working.
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
47 ///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
48 /// # 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
49 ///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
50 /// 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
51 /// more Rust Mercurial constructs.
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 /// 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
54 /// 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
55 /// `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
56 /// 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
57 /// 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
58 /// 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
59 /// 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
60 ///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
61 /// 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
62 /// 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
63 /// 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
64 /// mechanisms in other contexts.
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
65 pub struct Index {
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
66 index: PyObject,
43964
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
67 capi: &'static Revlog_CAPI,
41055
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
68 }
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
69
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
70 impl Index {
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
71 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: 44013
diff changeset
72 let capi = unsafe { revlog_capi::retrieve(py)? };
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
73 if capi.abi_version != REVLOG_CABI_VERSION {
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
74 return Err(PyErr::new::<ImportError, _>(
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
75 py,
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
76 format!(
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
77 "ABI version mismatch: the C ABI revlog version {} \
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
78 does not match the {} expected by Rust hg-cpython",
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
79 capi.abi_version, REVLOG_CABI_VERSION
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
80 ),
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
81 ));
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
82 }
41055
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
83 Ok(Index {
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
84 index: index,
44066
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44013
diff changeset
85 capi: capi,
41055
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
86 })
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
87 }
43965
ab3fd8077f5e rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents: 43964
diff changeset
88
ab3fd8077f5e rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents: 43964
diff changeset
89 /// 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: 43964
diff changeset
90 pub fn inner(&self) -> &PyObject {
ab3fd8077f5e rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents: 43964
diff changeset
91 &self.index
ab3fd8077f5e rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents: 43964
diff changeset
92 }
41055
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
93 }
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
94
41057
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41055
diff changeset
95 impl Clone for Index {
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41055
diff changeset
96 fn clone(&self) -> Self {
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41055
diff changeset
97 let guard = Python::acquire_gil();
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41055
diff changeset
98 Index {
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41055
diff changeset
99 index: self.index.clone_ref(guard.python()),
43964
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
100 capi: self.capi,
41057
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41055
diff changeset
101 }
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41055
diff changeset
102 }
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41055
diff changeset
103 }
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41055
diff changeset
104
44013
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43965
diff changeset
105 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: 43965
diff changeset
106 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: 43965
diff changeset
107 Index {
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43965
diff changeset
108 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: 43965
diff changeset
109 capi: self.capi,
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43965
diff changeset
110 }
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43965
diff changeset
111 }
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43965
diff changeset
112 }
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43965
diff changeset
113
41055
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
114 impl Graph for Index {
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
115 /// 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
116 fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> {
41310
ab0d762d89ef rust-cpython: raising error.WdirUnsupported
Georges Racinet <georges.racinet@octobus.net>
parents: 41057
diff changeset
117 if rev == WORKING_DIRECTORY_REVISION {
ab0d762d89ef rust-cpython: raising error.WdirUnsupported
Georges Racinet <georges.racinet@octobus.net>
parents: 41057
diff changeset
118 return Err(GraphError::WorkingDirectoryUnsupported);
ab0d762d89ef rust-cpython: raising error.WdirUnsupported
Georges Racinet <georges.racinet@octobus.net>
parents: 41057
diff changeset
119 }
41055
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
120 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
121 let code = unsafe {
43964
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
122 (self.capi.index_parents)(
41055
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
123 self.index.as_ptr(),
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
124 rev as c_int,
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
125 &mut res as *mut [c_int; 2],
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
126 )
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
127 };
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
128 match code {
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
129 0 => Ok(res),
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
130 _ => Err(GraphError::ParentOutOfRange(rev)),
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
131 }
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
132 }
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
133 }