##// END OF EJS Templates
revlog: using two new functions in C capsule from Rust code...
Georges Racinet -
r44989:16634951 default
parent child Browse files
Show More
@@ -39,6 +39,8 b' typedef struct {'
39
39
40 typedef struct {
40 typedef struct {
41 int abi_version;
41 int abi_version;
42 Py_ssize_t (*index_length)(const indexObject *);
43 const char *(*index_node)(indexObject *, Py_ssize_t);
42 int (*index_parents)(PyObject *, int, int *);
44 int (*index_parents)(PyObject *, int, int *);
43 } Revlog_CAPI;
45 } Revlog_CAPI;
44
46
@@ -2877,7 +2879,9 b' bail:'
2877 static Revlog_CAPI CAPI = {
2879 static Revlog_CAPI CAPI = {
2878 /* increment the abi_version field upon each change in the Revlog_CAPI
2880 /* increment the abi_version field upon each change in the Revlog_CAPI
2879 struct or in the ABI of the listed functions */
2881 struct or in the ABI of the listed functions */
2880 1,
2882 2,
2883 index_length,
2884 index_node,
2881 HgRevlogIndex_GetParents,
2885 HgRevlogIndex_GetParents,
2882 };
2886 };
2883
2887
@@ -44,6 +44,7 b' type NodeData = [u8; NODE_BYTES_LENGTH];'
44 /// [`nybbles_len`]: #method.nybbles_len
44 /// [`nybbles_len`]: #method.nybbles_len
45 /// [`ExactLengthRequired`]: struct.NodeError#variant.ExactLengthRequired
45 /// [`ExactLengthRequired`]: struct.NodeError#variant.ExactLengthRequired
46 #[derive(Clone, Debug, PartialEq)]
46 #[derive(Clone, Debug, PartialEq)]
47 #[repr(transparent)]
47 pub struct Node {
48 pub struct Node {
48 data: NodeData,
49 data: NodeData,
49 }
50 }
@@ -11,14 +11,21 b''
11 //! but this will take some time to get there.
11 //! but this will take some time to get there.
12
12
13 use cpython::{exc::ImportError, PyClone, PyErr, PyObject, PyResult, Python};
13 use cpython::{exc::ImportError, PyClone, PyErr, PyObject, PyResult, Python};
14 use hg::revlog::{Node, RevlogIndex};
14 use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION};
15 use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION};
15 use libc::c_int;
16 use libc::c_int;
16
17
17 const REVLOG_CABI_VERSION: c_int = 1;
18 const REVLOG_CABI_VERSION: c_int = 2;
18
19
19 #[repr(C)]
20 #[repr(C)]
20 pub struct Revlog_CAPI {
21 pub struct Revlog_CAPI {
21 abi_version: c_int,
22 abi_version: c_int,
23 index_length:
24 unsafe extern "C" fn(index: *mut revlog_capi::RawPyObject) -> c_int,
25 index_node: unsafe extern "C" fn(
26 index: *mut revlog_capi::RawPyObject,
27 rev: c_int,
28 ) -> *const Node,
22 index_parents: unsafe extern "C" fn(
29 index_parents: unsafe extern "C" fn(
23 index: *mut revlog_capi::RawPyObject,
30 index: *mut revlog_capi::RawPyObject,
24 rev: c_int,
31 rev: c_int,
@@ -131,3 +138,30 b' impl Graph for Index {'
131 }
138 }
132 }
139 }
133 }
140 }
141
142 impl RevlogIndex for Index {
143 /// Note C return type is Py_ssize_t (hence signed), but we shall
144 /// force it to unsigned, because it's a length
145 fn len(&self) -> usize {
146 unsafe { (self.capi.index_length)(self.index.as_ptr()) as usize }
147 }
148
149 fn node<'a>(&'a self, rev: Revision) -> Option<&'a Node> {
150 let raw = unsafe {
151 (self.capi.index_node)(self.index.as_ptr(), rev as c_int)
152 };
153 if raw.is_null() {
154 None
155 } else {
156 // TODO it would be much better for the C layer to give us
157 // a length, since the hash length will change in the near
158 // future, but that's probably out of scope for the nodemap
159 // patch series.
160 //
161 // The root of that unsafety relies in the signature of
162 // `capi.index_node()` itself: returning a `Node` pointer
163 // whereas it's a `char *` in the C counterpart.
164 Some(unsafe { &*raw })
165 }
166 }
167 }
General Comments 0
You need to be logged in to leave comments. Login now