Mercurial > public > mercurial-scm > hg
annotate rust/hg-cpython/src/cindex.rs @ 48178:f12a19d03d2c
fix: reduce number of tool executions
By grouping together (path, ctx) pairs according to the inputs they would
provide to fixer tools, we can deduplicate executions of fixer tools to
significantly reduce the amount of time spent running slow tools.
This change does not handle clean files in the working copy, which could still
be deduplicated against the files in the checked out commit. It's a little
harder to do that because the filerev is not available in the workingfilectx
(and it doesn't exist for added files).
Anecdotally, this change makes some real uses cases at Google 10x faster. I
think we were originally hesitant to do this because the benefits weren't
obvious, and implementing it efficiently is kind of tricky. If we simply
memoized the formatter execution function, we would be keeping tons of file
content in memory.
Also included is a regression test for a corner case that I broke with my first
attempt at optimizing this code.
Differential Revision: https://phab.mercurial-scm.org/D11280
author | Danny Hooper <hooper@google.com> |
---|---|
date | Thu, 02 Sep 2021 14:08:45 -0700 |
parents | 9d1a8829f959 |
children | 8e8737a1fa7d |
rev | line source |
---|---|
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 |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
21 const REVLOG_CABI_VERSION: c_int = 2; |
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, |
43959
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
32 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
|
33 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
|
34 rev: c_int, |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
35 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
|
36 ) -> c_int, |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
37 } |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
38 |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
39 py_capsule!( |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
40 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
|
41 as revlog_capi for Revlog_CAPI); |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
42 |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
43 /// 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
|
44 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
45 /// 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
|
46 /// - the C index object (`index` member) |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
47 /// - the `index_get_parents()` function (`parents` member) |
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 /// # Safety |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
50 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
51 /// 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
|
52 /// 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
|
53 /// to Python threads. |
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 /// 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
|
56 /// while working. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
57 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
58 /// # 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
|
59 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
60 /// 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
|
61 /// more Rust Mercurial constructs. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
62 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
63 /// 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
|
64 /// 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
|
65 /// `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
|
66 /// 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
|
67 /// 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
|
68 /// 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
|
69 /// 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
|
70 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
71 /// 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
|
72 /// 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
|
73 /// 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
|
74 /// mechanisms in other contexts. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
75 pub struct Index { |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
76 index: PyObject, |
43959
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
77 capi: &'static Revlog_CAPI, |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
78 } |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
79 |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
80 impl Index { |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
81 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
|
82 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
|
83 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
|
84 return Err(PyErr::new::<ImportError, _>( |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
85 py, |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
86 format!( |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
87 "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
|
88 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
|
89 capi.abi_version, REVLOG_CABI_VERSION |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
90 ), |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
91 )); |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
92 } |
47268
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
93 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
|
94 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
|
95 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
|
96 py, |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
97 "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
|
98 )); |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
99 } |
44973
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44504
diff
changeset
|
100 Ok(Index { index, capi }) |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
101 } |
43960
ab3fd8077f5e
rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents:
43959
diff
changeset
|
102 |
ab3fd8077f5e
rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents:
43959
diff
changeset
|
103 /// 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
|
104 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
|
105 &self.index |
ab3fd8077f5e
rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents:
43959
diff
changeset
|
106 } |
44504
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
107 |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
108 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
|
109 self.index.call_method( |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
110 py, |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
111 "append", |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
112 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
|
113 None, |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
114 ) |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
115 } |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
116 } |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
117 |
41054
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
118 impl Clone for Index { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
119 fn clone(&self) -> Self { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
120 let guard = Python::acquire_gil(); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
121 Index { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
122 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
|
123 capi: self.capi, |
41054
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
124 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
125 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
126 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
127 |
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
|
128 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
|
129 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
|
130 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
|
131 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
|
132 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
|
133 } |
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 } |
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 } |
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 |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
137 impl Graph for Index { |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
138 /// 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
|
139 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
|
140 if rev == WORKING_DIRECTORY_REVISION { |
ab0d762d89ef
rust-cpython: raising error.WdirUnsupported
Georges Racinet <georges.racinet@octobus.net>
parents:
41054
diff
changeset
|
141 return Err(GraphError::WorkingDirectoryUnsupported); |
ab0d762d89ef
rust-cpython: raising error.WdirUnsupported
Georges Racinet <georges.racinet@octobus.net>
parents:
41054
diff
changeset
|
142 } |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
143 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
|
144 let code = unsafe { |
43959
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
145 (self.capi.index_parents)( |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
146 self.index.as_ptr(), |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
147 rev as c_int, |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
148 &mut res as *mut [c_int; 2], |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
149 ) |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
150 }; |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
151 match code { |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
152 0 => Ok(res), |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
153 _ => Err(GraphError::ParentOutOfRange(rev)), |
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 } |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
156 } |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
157 |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
158 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
|
159 /// 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
|
160 /// 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
|
161 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
|
162 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
|
163 } |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
164 |
44973
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44504
diff
changeset
|
165 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
|
166 let raw = unsafe { |
46412
7d0405e458a0
persistent-nodemap: Fix Rust declarations for Revlog_CAPI signatures
Simon Sapin <simon.sapin@octobus.net>
parents:
44973
diff
changeset
|
167 (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
|
168 }; |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
169 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
|
170 None |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
171 } else { |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
172 // 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
|
173 // 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
|
174 // 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
|
175 // patch series. |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
176 // |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
177 // 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
|
178 // `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
|
179 // 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
|
180 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
|
181 } |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
182 } |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
183 } |