##// END OF EJS Templates
revlog: run rustfmt nightly...
Augie Fackler -
r44527:451d2217 default
parent child Browse files
Show More
@@ -1,232 +1,235 b''
1 1 // revlog.rs
2 2 //
3 3 // Copyright 2019 Georges Racinet <georges.racinet@octobus.net>
4 4 //
5 5 // This software may be used and distributed according to the terms of the
6 6 // GNU General Public License version 2 or any later version.
7 7
8 8 use crate::cindex;
9 9 use cpython::{
10 ObjectProtocol, PyClone, PyDict, PyModule, PyObject, PyResult, PyTuple, Python, PythonObject,
11 ToPyObject,
10 ObjectProtocol, PyClone, PyDict, PyModule, PyObject, PyResult, PyTuple,
11 Python, PythonObject, ToPyObject,
12 12 };
13 13 use hg::Revision;
14 14 use std::cell::RefCell;
15 15
16 16 /// Return a Struct implementing the Graph trait
17 pub(crate) fn pyindex_to_graph(py: Python, index: PyObject) -> PyResult<cindex::Index> {
17 pub(crate) fn pyindex_to_graph(
18 py: Python,
19 index: PyObject,
20 ) -> PyResult<cindex::Index> {
18 21 match index.extract::<MixedIndex>(py) {
19 22 Ok(midx) => Ok(midx.clone_cindex(py)),
20 23 Err(_) => cindex::Index::new(py, index),
21 24 }
22 25 }
23 26
24 27 py_class!(pub class MixedIndex |py| {
25 28 data cindex: RefCell<cindex::Index>;
26 29
27 30 def __new__(_cls, cindex: PyObject) -> PyResult<MixedIndex> {
28 31 Self::create_instance(py, RefCell::new(
29 32 cindex::Index::new(py, cindex)?))
30 33 }
31 34
32 35 /// Compatibility layer used for Python consumers needing access to the C index
33 36 ///
34 37 /// Only use case so far is `scmutil.shortesthexnodeidprefix`,
35 38 /// that may need to build a custom `nodetree`, based on a specified revset.
36 39 /// With a Rust implementation of the nodemap, we will be able to get rid of
37 40 /// this, by exposing our own standalone nodemap class,
38 41 /// ready to accept `MixedIndex`.
39 42 def get_cindex(&self) -> PyResult<PyObject> {
40 43 Ok(self.cindex(py).borrow().inner().clone_ref(py))
41 44 }
42 45
43 46
44 47 // Reforwarded C index API
45 48
46 49 // index_methods (tp_methods). Same ordering as in revlog.c
47 50
48 51 /// return the gca set of the given revs
49 52 def ancestors(&self, *args, **kw) -> PyResult<PyObject> {
50 53 self.call_cindex(py, "ancestors", args, kw)
51 54 }
52 55
53 56 /// return the heads of the common ancestors of the given revs
54 57 def commonancestorsheads(&self, *args, **kw) -> PyResult<PyObject> {
55 58 self.call_cindex(py, "commonancestorsheads", args, kw)
56 59 }
57 60
58 61 /// clear the index caches
59 62 def clearcaches(&self, *args, **kw) -> PyResult<PyObject> {
60 63 self.call_cindex(py, "clearcaches", args, kw)
61 64 }
62 65
63 66 /// get an index entry
64 67 def get(&self, *args, **kw) -> PyResult<PyObject> {
65 68 self.call_cindex(py, "get", args, kw)
66 69 }
67 70
68 71 /// return `rev` associated with a node or None
69 72 def get_rev(&self, *args, **kw) -> PyResult<PyObject> {
70 73 self.call_cindex(py, "get_rev", args, kw)
71 74 }
72 75
73 76 /// return True if the node exist in the index
74 77 def has_node(&self, *args, **kw) -> PyResult<PyObject> {
75 78 self.call_cindex(py, "has_node", args, kw)
76 79 }
77 80
78 81 /// return `rev` associated with a node or raise RevlogError
79 82 def rev(&self, *args, **kw) -> PyResult<PyObject> {
80 83 self.call_cindex(py, "rev", args, kw)
81 84 }
82 85
83 86 /// compute phases
84 87 def computephasesmapsets(&self, *args, **kw) -> PyResult<PyObject> {
85 88 self.call_cindex(py, "computephasesmapsets", args, kw)
86 89 }
87 90
88 91 /// reachableroots
89 92 def reachableroots2(&self, *args, **kw) -> PyResult<PyObject> {
90 93 self.call_cindex(py, "reachableroots2", args, kw)
91 94 }
92 95
93 96 /// get head revisions
94 97 def headrevs(&self, *args, **kw) -> PyResult<PyObject> {
95 98 self.call_cindex(py, "headrevs", args, kw)
96 99 }
97 100
98 101 /// get filtered head revisions
99 102 def headrevsfiltered(&self, *args, **kw) -> PyResult<PyObject> {
100 103 self.call_cindex(py, "headrevsfiltered", args, kw)
101 104 }
102 105
103 106 /// True if the object is a snapshot
104 107 def issnapshot(&self, *args, **kw) -> PyResult<PyObject> {
105 108 self.call_cindex(py, "issnapshot", args, kw)
106 109 }
107 110
108 111 /// Gather snapshot data in a cache dict
109 112 def findsnapshots(&self, *args, **kw) -> PyResult<PyObject> {
110 113 self.call_cindex(py, "findsnapshots", args, kw)
111 114 }
112 115
113 116 /// determine revisions with deltas to reconstruct fulltext
114 117 def deltachain(&self, *args, **kw) -> PyResult<PyObject> {
115 118 self.call_cindex(py, "deltachain", args, kw)
116 119 }
117 120
118 121 /// slice planned chunk read to reach a density threshold
119 122 def slicechunktodensity(&self, *args, **kw) -> PyResult<PyObject> {
120 123 self.call_cindex(py, "slicechunktodensity", args, kw)
121 124 }
122 125
123 126 /// append an index entry
124 127 def append(&self, *args, **kw) -> PyResult<PyObject> {
125 128 self.call_cindex(py, "append", args, kw)
126 129 }
127 130
128 131 /// match a potentially ambiguous node ID
129 132 def partialmatch(&self, *args, **kw) -> PyResult<PyObject> {
130 133 self.call_cindex(py, "partialmatch", args, kw)
131 134 }
132 135
133 136 /// find length of shortest hex nodeid of a binary ID
134 137 def shortest(&self, *args, **kw) -> PyResult<PyObject> {
135 138 self.call_cindex(py, "shortest", args, kw)
136 139 }
137 140
138 141 /// stats for the index
139 142 def stats(&self, *args, **kw) -> PyResult<PyObject> {
140 143 self.call_cindex(py, "stats", args, kw)
141 144 }
142 145
143 146 // index_sequence_methods and index_mapping_methods.
144 147 //
145 148 // Since we call back through the high level Python API,
146 149 // there's no point making a distinction between index_get
147 150 // and index_getitem.
148 151
149 152 def __len__(&self) -> PyResult<usize> {
150 153 self.cindex(py).borrow().inner().len(py)
151 154 }
152 155
153 156 def __getitem__(&self, key: PyObject) -> PyResult<PyObject> {
154 157 // this conversion seems needless, but that's actually because
155 158 // `index_getitem` does not handle conversion from PyLong,
156 159 // which expressions such as [e for e in index] internally use.
157 160 // Note that we don't seem to have a direct way to call
158 161 // PySequence_GetItem (does the job), which would be better for
159 162 // for performance
160 163 let key = match key.extract::<Revision>(py) {
161 164 Ok(rev) => rev.to_py_object(py).into_object(),
162 165 Err(_) => key,
163 166 };
164 167 self.cindex(py).borrow().inner().get_item(py, key)
165 168 }
166 169
167 170 def __setitem__(&self, key: PyObject, value: PyObject) -> PyResult<()> {
168 171 self.cindex(py).borrow().inner().set_item(py, key, value)
169 172 }
170 173
171 174 def __delitem__(&self, key: PyObject) -> PyResult<()> {
172 175 self.cindex(py).borrow().inner().del_item(py, key)
173 176 }
174 177
175 178 def __contains__(&self, item: PyObject) -> PyResult<bool> {
176 179 // ObjectProtocol does not seem to provide contains(), so
177 180 // this is an equivalent implementation of the index_contains()
178 181 // defined in revlog.c
179 182 let cindex = self.cindex(py).borrow();
180 183 match item.extract::<Revision>(py) {
181 184 Ok(rev) => {
182 185 Ok(rev >= -1 && rev < cindex.inner().len(py)? as Revision)
183 186 }
184 187 Err(_) => {
185 188 cindex.inner().call_method(
186 189 py,
187 190 "has_node",
188 191 PyTuple::new(py, &[item]),
189 192 None)?
190 193 .extract(py)
191 194 }
192 195 }
193 196 }
194 197
195 198
196 199 });
197 200
198 201 impl MixedIndex {
199 202 /// forward a method call to the underlying C index
200 203 fn call_cindex(
201 204 &self,
202 205 py: Python,
203 206 name: &str,
204 207 args: &PyTuple,
205 208 kwargs: Option<&PyDict>,
206 209 ) -> PyResult<PyObject> {
207 210 self.cindex(py)
208 211 .borrow()
209 212 .inner()
210 213 .call_method(py, name, args, kwargs)
211 214 }
212 215
213 216 pub fn clone_cindex(&self, py: Python) -> cindex::Index {
214 217 self.cindex(py).borrow().clone_ref(py)
215 218 }
216 219 }
217 220
218 221 /// Create the module, with __package__ given from parent
219 222 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
220 223 let dotted_name = &format!("{}.revlog", package);
221 224 let m = PyModule::new(py, dotted_name)?;
222 225 m.add(py, "__package__", package)?;
223 226 m.add(py, "__doc__", "RevLog - Rust implementations")?;
224 227
225 228 m.add_class::<MixedIndex>(py)?;
226 229
227 230 let sys = PyModule::import(py, "sys")?;
228 231 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
229 232 sys_modules.set_item(py, dotted_name, &m)?;
230 233
231 234 Ok(m)
232 235 }
General Comments 0
You need to be logged in to leave comments. Login now