annotate rust/hg-cpython/src/revlog.rs @ 51279:8b89f7cc953a

rust-index: allow inlining VCSGraph parents across crates
author Rapha?l Gom?s <rgomes@octobus.net>
date Thu, 14 Dec 2023 11:52:05 +0100
parents 24d3298189d7
children 9088c6d65ef6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
43951
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
1 // revlog.rs
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
2 //
44516
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
3 // Copyright 2019-2020 Georges Racinet <georges.racinet@octobus.net>
43951
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
4 //
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
5 // This software may be used and distributed according to the terms of the
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
6 // GNU General Public License version 2 or any later version.
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
7
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
8 use crate::{
51243
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
9 conversion::{rev_pyiter_collect, rev_pyiter_collect_or_else},
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
10 utils::{node_from_py_bytes, node_from_py_object},
50990
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50988
diff changeset
11 PyRevision,
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
12 };
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
13 use cpython::{
44520
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
14 buffer::{Element, PyBuffer},
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
15 exc::{IndexError, ValueError},
51269
8b243e2a3bc4 rust-index: a property to identify the Rust index as such
Georges Racinet <georges.racinet@octobus.net>
parents: 51268
diff changeset
16 ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyInt, PyList,
8b243e2a3bc4 rust-index: a property to identify the Rust index as such
Georges Racinet <georges.racinet@octobus.net>
parents: 51268
diff changeset
17 PyModule, PyObject, PyResult, PySet, PyString, PyTuple, Python,
8b243e2a3bc4 rust-index: a property to identify the Rust index as such
Georges Racinet <georges.racinet@octobus.net>
parents: 51268
diff changeset
18 PythonObject, ToPyObject, UnsafePyLeaked,
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
19 };
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
20 use hg::{
51233
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
21 errors::HgError,
51250
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51246
diff changeset
22 index::{
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51246
diff changeset
23 IndexHeader, Phase, RevisionDataParams, SnapshotsCache,
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51246
diff changeset
24 INDEX_ENTRY_SIZE,
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51246
diff changeset
25 },
51268
8dbd985733ff rust-cpython-revlog: renamed NodeTree import as CoreNodeTree
Georges Racinet <georges.racinet@octobus.net>
parents: 51267
diff changeset
26 nodemap::{Block, NodeMapError, NodeTree as CoreNodeTree},
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
27 revlog::{nodemap::NodeMap, Graph, NodePrefix, RevlogError, RevlogIndex},
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
28 BaseRevision, Node, Revision, UncheckedRevision, NULL_REVISION,
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
29 };
51241
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
30 use std::{cell::RefCell, collections::HashMap};
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
31 use vcsgraph::graph::Graph as VCSGraph;
43951
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
32
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
33 pub struct PySharedIndex {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
34 /// The underlying hg-core index
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
35 pub(crate) inner: &'static hg::index::Index,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
36 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
37
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
38 /// Return a Struct implementing the Graph trait
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
39 pub(crate) fn py_rust_index_to_graph(
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
40 py: Python,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
41 index: PyObject,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
42 ) -> PyResult<UnsafePyLeaked<PySharedIndex>> {
51275
f94c10334bcb rust-index: renamed `MixedIndex` as `Index`
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51274
diff changeset
43 let midx = index.extract::<Index>(py)?;
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
44 let leaked = midx.index(py).leak_immutable();
51276
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51275
diff changeset
45 // Safety: we don't leak the "faked" reference out of the `UnsafePyLeaked`
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
46 Ok(unsafe { leaked.map(py, |idx| PySharedIndex { inner: idx }) })
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
47 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
48
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
49 impl Clone for PySharedIndex {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
50 fn clone(&self) -> Self {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
51 Self { inner: self.inner }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
52 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
53 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
54
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
55 impl Graph for PySharedIndex {
51279
8b89f7cc953a rust-index: allow inlining VCSGraph parents across crates
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51276
diff changeset
56 #[inline(always)]
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
57 fn parents(&self, rev: Revision) -> Result<[Revision; 2], hg::GraphError> {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
58 self.inner.parents(rev)
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
59 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
60 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
61
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
62 impl VCSGraph for PySharedIndex {
51279
8b89f7cc953a rust-index: allow inlining VCSGraph parents across crates
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51276
diff changeset
63 #[inline(always)]
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
64 fn parents(
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
65 &self,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
66 rev: BaseRevision,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
67 ) -> Result<vcsgraph::graph::Parents, vcsgraph::graph::GraphReadError>
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
68 {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
69 // FIXME This trait should be reworked to decide between Revision
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
70 // and UncheckedRevision, get better errors names, etc.
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
71 match Graph::parents(self, Revision(rev)) {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
72 Ok(parents) => {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
73 Ok(vcsgraph::graph::Parents([parents[0].0, parents[1].0]))
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
74 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
75 Err(hg::GraphError::ParentOutOfRange(rev)) => {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
76 Err(vcsgraph::graph::GraphReadError::KeyedInvalidKey(rev.0))
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
77 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
78 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
79 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
80 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
81
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
82 impl RevlogIndex for PySharedIndex {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
83 fn len(&self) -> usize {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
84 self.inner.len()
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
85 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
86 fn node(&self, rev: Revision) -> Option<&Node> {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
87 self.inner.node(rev)
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
88 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
89 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
90
51275
f94c10334bcb rust-index: renamed `MixedIndex` as `Index`
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51274
diff changeset
91 py_class!(pub class Index |py| {
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
92 @shared data index: hg::index::Index;
51268
8dbd985733ff rust-cpython-revlog: renamed NodeTree import as CoreNodeTree
Georges Racinet <georges.racinet@octobus.net>
parents: 51267
diff changeset
93 data nt: RefCell<Option<CoreNodeTree>>;
44519
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
94 data docket: RefCell<Option<PyObject>>;
44520
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
95 // Holds a reference to the mmap'ed persistent nodemap data
51207
8ade5e6cdb61 rust-mixed-index: rename variable to make the next change clearer
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51118
diff changeset
96 data nodemap_mmap: RefCell<Option<PyBuffer>>;
51211
6ec8387eb0be rust-index: pass data down to the Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51208
diff changeset
97 // Holds a reference to the mmap'ed persistent index data
6ec8387eb0be rust-index: pass data down to the Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51208
diff changeset
98 data index_mmap: RefCell<Option<PyBuffer>>;
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
99
51211
6ec8387eb0be rust-index: pass data down to the Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51208
diff changeset
100 def __new__(
6ec8387eb0be rust-index: pass data down to the Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51208
diff changeset
101 _cls,
51212
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51211
diff changeset
102 data: PyObject,
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51211
diff changeset
103 default_header: u32,
51275
f94c10334bcb rust-index: renamed `MixedIndex` as `Index`
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51274
diff changeset
104 ) -> PyResult<Self> {
51274
96e05f1a99bd rust-index: stop instantiating a C Index
Georges Racinet <georges.racinet@octobus.net>
parents: 51272
diff changeset
105 Self::new(py, data, default_header)
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
106 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
107
44015
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44014
diff changeset
108 /// Compatibility layer used for Python consumers needing access to the C index
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44014
diff changeset
109 ///
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44014
diff changeset
110 /// Only use case so far is `scmutil.shortesthexnodeidprefix`,
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44014
diff changeset
111 /// that may need to build a custom `nodetree`, based on a specified revset.
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44014
diff changeset
112 /// With a Rust implementation of the nodemap, we will be able to get rid of
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44014
diff changeset
113 /// this, by exposing our own standalone nodemap class,
51274
96e05f1a99bd rust-index: stop instantiating a C Index
Georges Racinet <georges.racinet@octobus.net>
parents: 51272
diff changeset
114 /// ready to accept `Index`.
96e05f1a99bd rust-index: stop instantiating a C Index
Georges Racinet <georges.racinet@octobus.net>
parents: 51272
diff changeset
115 /* def get_cindex(&self) -> PyResult<PyObject> {
44015
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44014
diff changeset
116 Ok(self.cindex(py).borrow().inner().clone_ref(py))
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44014
diff changeset
117 }
51274
96e05f1a99bd rust-index: stop instantiating a C Index
Georges Racinet <georges.racinet@octobus.net>
parents: 51272
diff changeset
118 */
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
119 // Index API involving nodemap, as defined in mercurial/pure/parsers.py
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
120
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
121 /// Return Revision if found, raises a bare `error.RevlogError`
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
122 /// in case of ambiguity, same as C version does
50990
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50988
diff changeset
123 def get_rev(&self, node: PyBytes) -> PyResult<Option<PyRevision>> {
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
124 let opt = self.get_nodetree(py)?.borrow();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
125 let nt = opt.as_ref().unwrap();
51217
f95f70cf2ee2 rust-index: check rindex and cindex return the same get_rev
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51216
diff changeset
126 let ridx = &*self.index(py).borrow();
47894
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47795
diff changeset
127 let node = node_from_py_bytes(py, &node)?;
51217
f95f70cf2ee2 rust-index: check rindex and cindex return the same get_rev
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51216
diff changeset
128 let rust_rev =
f95f70cf2ee2 rust-index: check rindex and cindex return the same get_rev
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51216
diff changeset
129 nt.find_bin(ridx, node.into()).map_err(|e| nodemap_error(py, e))?;
f95f70cf2ee2 rust-index: check rindex and cindex return the same get_rev
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51216
diff changeset
130 Ok(rust_rev.map(Into::into))
f95f70cf2ee2 rust-index: check rindex and cindex return the same get_rev
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51216
diff changeset
131
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
132 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
133
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
134 /// same as `get_rev()` but raises a bare `error.RevlogError` if node
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
135 /// is not found.
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
136 ///
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
137 /// No need to repeat `node` in the exception, `mercurial/revlog.py`
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
138 /// will catch and rewrap with it
50990
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50988
diff changeset
139 def rev(&self, node: PyBytes) -> PyResult<PyRevision> {
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
140 self.get_rev(py, node)?.ok_or_else(|| revlog_error(py))
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
141 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
142
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
143 /// return True if the node exist in the index
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
144 def has_node(&self, node: PyBytes) -> PyResult<bool> {
51225
297fa956b6c4 rust-index: optim note for post-scaffolding removal
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
145 // TODO OPTIM we could avoid a needless conversion here,
297fa956b6c4 rust-index: optim note for post-scaffolding removal
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
146 // to do when scaffolding for pure Rust switch is removed,
297fa956b6c4 rust-index: optim note for post-scaffolding removal
Georges Racinet <georges.racinet@octobus.net>
parents: 51224
diff changeset
147 // as `get_rev()` currently does the necessary assertions
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
148 self.get_rev(py, node).map(|opt| opt.is_some())
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
149 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
150
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
151 /// find length of shortest hex nodeid of a binary ID
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
152 def shortest(&self, node: PyBytes) -> PyResult<usize> {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
153 let opt = self.get_nodetree(py)?.borrow();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
154 let nt = opt.as_ref().unwrap();
51229
274abd1562a2 rust-index: use the rust index in `shortest`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51228
diff changeset
155 let idx = &*self.index(py).borrow();
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
156 match nt.unique_prefix_len_node(idx, &node_from_py_bytes(py, &node)?)
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
157 {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
158 Ok(Some(l)) => Ok(l),
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
159 Ok(None) => Err(revlog_error(py)),
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
160 Err(e) => Err(nodemap_error(py, e)),
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
161 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
162 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
163
47894
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47795
diff changeset
164 def partialmatch(&self, node: PyObject) -> PyResult<Option<PyBytes>> {
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
165 let opt = self.get_nodetree(py)?.borrow();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
166 let nt = opt.as_ref().unwrap();
51231
72d16685d63a rust-index: use the Rust index in `partialmatch`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51229
diff changeset
167 let idx = &*self.index(py).borrow();
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
168
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
169 let node_as_string = if cfg!(feature = "python3-sys") {
47894
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47795
diff changeset
170 node.cast_as::<PyString>(py)?.to_string(py)?.to_string()
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
171 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
172 else {
47894
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47795
diff changeset
173 let node = node.extract::<PyBytes>(py)?;
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
174 String::from_utf8_lossy(node.data(py)).to_string()
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
175 };
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
176
49373
455fce57e89e rust: don't swallow valuable error information
Rapha?l Gom?s <rgomes@octobus.net>
parents: 47894
diff changeset
177 let prefix = NodePrefix::from_hex(&node_as_string)
455fce57e89e rust: don't swallow valuable error information
Rapha?l Gom?s <rgomes@octobus.net>
parents: 47894
diff changeset
178 .map_err(|_| PyErr::new::<ValueError, _>(
455fce57e89e rust: don't swallow valuable error information
Rapha?l Gom?s <rgomes@octobus.net>
parents: 47894
diff changeset
179 py, format!("Invalid node or prefix '{}'", node_as_string))
455fce57e89e rust: don't swallow valuable error information
Rapha?l Gom?s <rgomes@octobus.net>
parents: 47894
diff changeset
180 )?;
46500
18a261b11b20 rust: Remove hex parsing from the nodemap
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
181
47894
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47795
diff changeset
182 nt.find_bin(idx, prefix)
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47795
diff changeset
183 // TODO make an inner API returning the node directly
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47795
diff changeset
184 .map(|opt| opt.map(
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47795
diff changeset
185 |rev| PyBytes::new(py, idx.node(rev).unwrap().as_bytes())))
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47795
diff changeset
186 .map_err(|e| nodemap_error(py, e))
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47795
diff changeset
187
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
188 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
189
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
190 /// append an index entry
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
191 def append(&self, tup: PyTuple) -> PyResult<PyObject> {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
192 if tup.len(py) < 8 {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
193 // this is better than the panic promised by tup.get_item()
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
194 return Err(
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
195 PyErr::new::<IndexError, _>(py, "tuple index out of range"))
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
196 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
197 let node_bytes = tup.get_item(py, 7).extract(py)?;
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
198 let node = node_from_py_object(py, &node_bytes)?;
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
199
51214
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51213
diff changeset
200 let rev = self.len(py)? as BaseRevision;
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
201
50990
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50988
diff changeset
202 // This is ok since we will just add the revision to the index
51214
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51213
diff changeset
203 let rev = Revision(rev);
51213
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
204 self.index(py)
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
205 .borrow_mut()
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
206 .append(py_tuple_to_revision_data_params(py, tup)?)
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
207 .unwrap();
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
208 let idx = &*self.index(py).borrow();
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
209 self.get_nodetree(py)?.borrow_mut().as_mut().unwrap()
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
210 .insert(idx, &node, rev)
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
211 .map_err(|e| nodemap_error(py, e))?;
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
212 Ok(py.None())
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
213 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
214
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
215 def __delitem__(&self, key: PyObject) -> PyResult<()> {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
216 // __delitem__ is both for `del idx[r]` and `del idx[r1:r2]`
51271
a8ca22119385 rust-index: add support for `del index[r]`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51270
diff changeset
217 let start = if let Ok(rev) = key.extract(py) {
a8ca22119385 rust-index: add support for `del index[r]`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51270
diff changeset
218 UncheckedRevision(rev)
a8ca22119385 rust-index: add support for `del index[r]`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51270
diff changeset
219 } else {
a8ca22119385 rust-index: add support for `del index[r]`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51270
diff changeset
220 let start = key.getattr(py, "start")?;
a8ca22119385 rust-index: add support for `del index[r]`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51270
diff changeset
221 UncheckedRevision(start.extract(py)?)
a8ca22119385 rust-index: add support for `del index[r]`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51270
diff changeset
222 };
51216
f6403bcd9f96 rust-index: synchronize remove to Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51215
diff changeset
223 let start = self.index(py)
f6403bcd9f96 rust-index: synchronize remove to Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51215
diff changeset
224 .borrow()
f6403bcd9f96 rust-index: synchronize remove to Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51215
diff changeset
225 .check_revision(start)
f6403bcd9f96 rust-index: synchronize remove to Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51215
diff changeset
226 .ok_or_else(|| {
f6403bcd9f96 rust-index: synchronize remove to Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51215
diff changeset
227 nodemap_error(py, NodeMapError::RevisionNotInIndex(start))
f6403bcd9f96 rust-index: synchronize remove to Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51215
diff changeset
228 })?;
f6403bcd9f96 rust-index: synchronize remove to Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51215
diff changeset
229 self.index(py).borrow_mut().remove(start).unwrap();
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
230 let mut opt = self.get_nodetree(py)?.borrow_mut();
49987
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49373
diff changeset
231 let nt = opt.as_mut().unwrap();
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
232 nt.invalidate_all();
49987
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49373
diff changeset
233 self.fill_nodemap(py, nt)?;
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
234 Ok(())
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
235 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
236
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
237 //
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
238 // Index methods previously reforwarded to C index (tp_methods)
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
239 // Same ordering as in revlog.c
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
240 //
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
241
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
242 /// return the gca set of the given revs
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
243 def ancestors(&self, *args, **_kw) -> PyResult<PyObject> {
51246
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
244 let rust_res = self.inner_ancestors(py, args)?;
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
245 Ok(rust_res)
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
246 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
247
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
248 /// return the heads of the common ancestors of the given revs
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
249 def commonancestorsheads(&self, *args, **_kw) -> PyResult<PyObject> {
51246
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
250 let rust_res = self.inner_commonancestorsheads(py, args)?;
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
251 Ok(rust_res)
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
252 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
253
44521
cadcc8c20860 rust-nodemap: also clear Rust data in `clearcaches`
Georges Racinet <georges.racinet@octobus.net>
parents: 44520
diff changeset
254 /// Clear the index caches and inner py_class data.
cadcc8c20860 rust-nodemap: also clear Rust data in `clearcaches`
Georges Racinet <georges.racinet@octobus.net>
parents: 44520
diff changeset
255 /// It is Python's responsibility to call `update_nodemap_data` again.
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
256 def clearcaches(&self) -> PyResult<PyObject> {
44521
cadcc8c20860 rust-nodemap: also clear Rust data in `clearcaches`
Georges Racinet <georges.racinet@octobus.net>
parents: 44520
diff changeset
257 self.nt(py).borrow_mut().take();
cadcc8c20860 rust-nodemap: also clear Rust data in `clearcaches`
Georges Racinet <georges.racinet@octobus.net>
parents: 44520
diff changeset
258 self.docket(py).borrow_mut().take();
51207
8ade5e6cdb61 rust-mixed-index: rename variable to make the next change clearer
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51118
diff changeset
259 self.nodemap_mmap(py).borrow_mut().take();
51255
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51254
diff changeset
260 self.index(py).borrow().clear_caches();
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
261 Ok(py.None())
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
262 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
263
47075
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
264 /// return the raw binary string representing a revision
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
265 def entry_binary(&self, *args, **_kw) -> PyResult<PyObject> {
51224
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51223
diff changeset
266 let rindex = self.index(py).borrow();
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51223
diff changeset
267 let rev = UncheckedRevision(args.get_item(py, 0).extract(py)?);
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51223
diff changeset
268 let rust_bytes = rindex.check_revision(rev).and_then(
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51223
diff changeset
269 |r| rindex.entry_binary(r))
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51223
diff changeset
270 .ok_or_else(|| rev_not_in_index(py, rev))?;
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51223
diff changeset
271 let rust_res = PyBytes::new(py, rust_bytes).into_object();
7434747343ab rust-index: check that the entry bytes are the same in both indexes
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51223
diff changeset
272 Ok(rust_res)
47075
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
273 }
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
274
47078
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47075
diff changeset
275 /// return a binary packed version of the header
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
276 def pack_header(&self, *args, **_kw) -> PyResult<PyObject> {
51219
51cc12158f97 rust-index: add `pack_header` support
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51218
diff changeset
277 let rindex = self.index(py).borrow();
51cc12158f97 rust-index: add `pack_header` support
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51218
diff changeset
278 let packed = rindex.pack_header(args.get_item(py, 0).extract(py)?);
51223
16d477bb0078 rust-index: return variables systematic naming convention
Georges Racinet <georges.racinet@octobus.net>
parents: 51222
diff changeset
279 let rust_res = PyBytes::new(py, &packed).into_object();
16d477bb0078 rust-index: return variables systematic naming convention
Georges Racinet <georges.racinet@octobus.net>
parents: 51222
diff changeset
280 Ok(rust_res)
47078
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47075
diff changeset
281 }
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47075
diff changeset
282
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
283 /// compute phases
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
284 def computephasesmapsets(&self, *args, **_kw) -> PyResult<PyObject> {
51241
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
285 let py_roots = args.get_item(py, 0).extract::<PyDict>(py)?;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
286 let rust_res = self.inner_computephasesmapsets(py, py_roots)?;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
287 Ok(rust_res)
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
288 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
289
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
290 /// reachableroots
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
291 def reachableroots2(&self, *args, **_kw) -> PyResult<PyObject> {
51243
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
292 let rust_res = self.inner_reachableroots2(
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
293 py,
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
294 UncheckedRevision(args.get_item(py, 0).extract(py)?),
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
295 args.get_item(py, 1),
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
296 args.get_item(py, 2),
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
297 args.get_item(py, 3).extract(py)?,
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
298 )?;
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
299 Ok(rust_res)
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
300 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
301
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
302 /// get head revisions
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
303 def headrevs(&self) -> PyResult<PyObject> {
51236
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
304 let rust_res = self.inner_headrevs(py)?;
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
305 Ok(rust_res)
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
306 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
307
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
308 /// get filtered head revisions
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
309 def headrevsfiltered(&self, *args, **_kw) -> PyResult<PyObject> {
51237
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51236
diff changeset
310 let rust_res = self.inner_headrevsfiltered(py, &args.get_item(py, 0))?;
51238
898674a4dbc7 rust-index: headrevsfiltered() returning Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51237
diff changeset
311 Ok(rust_res)
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
312 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
313
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
314 /// True if the object is a snapshot
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
315 def issnapshot(&self, *args, **_kw) -> PyResult<bool> {
51232
b8c89957a6b7 rust-index: add `is_snapshot` method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51231
diff changeset
316 let index = self.index(py).borrow();
b8c89957a6b7 rust-index: add `is_snapshot` method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51231
diff changeset
317 let result = index
b8c89957a6b7 rust-index: add `is_snapshot` method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51231
diff changeset
318 .is_snapshot(UncheckedRevision(args.get_item(py, 0).extract(py)?))
b8c89957a6b7 rust-index: add `is_snapshot` method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51231
diff changeset
319 .map_err(|e| {
b8c89957a6b7 rust-index: add `is_snapshot` method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51231
diff changeset
320 PyErr::new::<cpython::exc::ValueError, _>(py, e.to_string())
b8c89957a6b7 rust-index: add `is_snapshot` method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51231
diff changeset
321 })?;
b8c89957a6b7 rust-index: add `is_snapshot` method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51231
diff changeset
322 Ok(result)
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
323 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
324
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
325 /// Gather snapshot data in a cache dict
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
326 def findsnapshots(&self, *args, **_kw) -> PyResult<PyObject> {
51233
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
327 let index = self.index(py).borrow();
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
328 let cache: PyDict = args.get_item(py, 0).extract(py)?;
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
329 // this methods operates by setting new values in the cache,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
330 // hence we will compare results by letting the C implementation
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
331 // operate over a deepcopy of the cache, and finally compare both
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
332 // caches.
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
333 let c_cache = PyDict::new(py);
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
334 for (k, v) in cache.items(py) {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
335 c_cache.set_item(py, k, PySet::new(py, v)?)?;
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
336 }
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
337
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
338 let start_rev = UncheckedRevision(args.get_item(py, 1).extract(py)?);
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
339 let end_rev = UncheckedRevision(args.get_item(py, 2).extract(py)?);
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
340 let mut cache_wrapper = PySnapshotsCache{ py, dict: cache };
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
341 index.find_snapshots(
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
342 start_rev,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
343 end_rev,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
344 &mut cache_wrapper,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
345 ).map_err(|_| revlog_error(py))?;
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
346 Ok(py.None())
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
347 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
348
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
349 /// determine revisions with deltas to reconstruct fulltext
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
350 def deltachain(&self, *args, **_kw) -> PyResult<PyObject> {
51234
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
351 let index = self.index(py).borrow();
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
352 let rev = args.get_item(py, 0).extract::<BaseRevision>(py)?.into();
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
353 let stop_rev =
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
354 args.get_item(py, 1).extract::<Option<BaseRevision>>(py)?;
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
355 let rev = index.check_revision(rev).ok_or_else(|| {
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
356 nodemap_error(py, NodeMapError::RevisionNotInIndex(rev))
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
357 })?;
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
358 let stop_rev = if let Some(stop_rev) = stop_rev {
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
359 let stop_rev = UncheckedRevision(stop_rev);
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
360 Some(index.check_revision(stop_rev).ok_or_else(|| {
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
361 nodemap_error(py, NodeMapError::RevisionNotInIndex(stop_rev))
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
362 })?)
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
363 } else {None};
51256
456e0fe702e8 rust-index: honour incoming using_general_delta in `deltachain`
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51255
diff changeset
364 let using_general_delta = args.get_item(py, 2)
456e0fe702e8 rust-index: honour incoming using_general_delta in `deltachain`
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51255
diff changeset
365 .extract::<Option<u32>>(py)?
456e0fe702e8 rust-index: honour incoming using_general_delta in `deltachain`
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51255
diff changeset
366 .map(|i| i != 0);
456e0fe702e8 rust-index: honour incoming using_general_delta in `deltachain`
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51255
diff changeset
367 let (chain, stopped) = index.delta_chain(
456e0fe702e8 rust-index: honour incoming using_general_delta in `deltachain`
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51255
diff changeset
368 rev, stop_rev, using_general_delta
456e0fe702e8 rust-index: honour incoming using_general_delta in `deltachain`
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51255
diff changeset
369 ).map_err(|e| {
51234
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
370 PyErr::new::<cpython::exc::ValueError, _>(py, e.to_string())
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
371 })?;
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
372
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
373 let chain: Vec<_> = chain.into_iter().map(|r| r.0).collect();
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
374 Ok(
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
375 PyTuple::new(
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
376 py,
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
377 &[
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
378 chain.into_py_object(py).into_object(),
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
379 stopped.into_py_object(py).into_object()
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
380 ]
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
381 ).into_object()
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
382 )
62e39bef36ca rust-index: add support for delta-chain computation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51233
diff changeset
383
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
384 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
385
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
386 /// slice planned chunk read to reach a density threshold
51267
41e19e8a6133 rust-index: stop using C index
Georges Racinet <georges.racinet@octobus.net>
parents: 51266
diff changeset
387 def slicechunktodensity(&self, *args, **_kw) -> PyResult<PyObject> {
51239
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
388 let rust_res = self.inner_slicechunktodensity(
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
389 py,
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
390 args.get_item(py, 0),
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
391 args.get_item(py, 1).extract(py)?,
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
392 args.get_item(py, 2).extract(py)?
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
393 )?;
51240
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
394 Ok(rust_res)
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
395 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
396
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
397 // index_sequence_methods and index_mapping_methods.
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
398 //
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
399 // Since we call back through the high level Python API,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
400 // there's no point making a distinction between index_get
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
401 // and index_getitem.
51226
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
402 // gracinet 2023: this above is no longer true for the pure Rust impl
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
403
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
404 def __len__(&self) -> PyResult<usize> {
51214
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51213
diff changeset
405 self.len(py)
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
406 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
407
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
408 def __getitem__(&self, key: PyObject) -> PyResult<PyObject> {
51226
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
409 let rust_res = self.inner_getitem(py, key.clone_ref(py))?;
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
410 Ok(rust_res)
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
411 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
412
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
413 def __contains__(&self, item: PyObject) -> PyResult<bool> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
414 // ObjectProtocol does not seem to provide contains(), so
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
415 // this is an equivalent implementation of the index_contains()
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
416 // defined in revlog.c
50988
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49987
diff changeset
417 match item.extract::<i32>(py) {
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
418 Ok(rev) => {
51214
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51213
diff changeset
419 Ok(rev >= -1 && rev < self.len(py)? as BaseRevision)
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
420 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
421 Err(_) => {
51228
b67cd0d0e976 rust-index: add checks that `__contains__` is synchronized
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51227
diff changeset
422 let item_bytes: PyBytes = item.extract(py)?;
b67cd0d0e976 rust-index: add checks that `__contains__` is synchronized
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51227
diff changeset
423 let rust_res = self.has_node(py, item_bytes)?;
b67cd0d0e976 rust-index: add checks that `__contains__` is synchronized
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51227
diff changeset
424 Ok(rust_res)
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
425 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
426 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
427 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
428
44518
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
429 def nodemap_data_all(&self) -> PyResult<PyBytes> {
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
430 self.inner_nodemap_data_all(py)
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
431 }
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
432
44519
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
433 def nodemap_data_incremental(&self) -> PyResult<PyObject> {
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
434 self.inner_nodemap_data_incremental(py)
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
435 }
44520
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
436 def update_nodemap_data(
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
437 &self,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
438 docket: PyObject,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
439 nm_data: PyObject
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
440 ) -> PyResult<PyObject> {
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
441 self.inner_update_nodemap_data(py, docket, nm_data)
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
442 }
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
443
46974
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46500
diff changeset
444 @property
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46500
diff changeset
445 def entry_size(&self) -> PyResult<PyInt> {
51250
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51246
diff changeset
446 let rust_res: PyInt = INDEX_ENTRY_SIZE.to_py_object(py);
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51246
diff changeset
447 Ok(rust_res)
46974
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46500
diff changeset
448 }
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
449
47279
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
450 @property
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
451 def rust_ext_compat(&self) -> PyResult<PyInt> {
51250
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51246
diff changeset
452 // will be entirely removed when the Rust index yet useful to
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51246
diff changeset
453 // implement in Rust to detangle things when removing `self.cindex`
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51246
diff changeset
454 let rust_res: PyInt = 1.to_py_object(py);
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51246
diff changeset
455 Ok(rust_res)
47279
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
456 }
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
457
51269
8b243e2a3bc4 rust-index: a property to identify the Rust index as such
Georges Racinet <georges.racinet@octobus.net>
parents: 51268
diff changeset
458 @property
8b243e2a3bc4 rust-index: a property to identify the Rust index as such
Georges Racinet <georges.racinet@octobus.net>
parents: 51268
diff changeset
459 def is_rust(&self) -> PyResult<PyBool> {
8b243e2a3bc4 rust-index: a property to identify the Rust index as such
Georges Racinet <georges.racinet@octobus.net>
parents: 51268
diff changeset
460 Ok(false.to_py_object(py))
8b243e2a3bc4 rust-index: a property to identify the Rust index as such
Georges Racinet <georges.racinet@octobus.net>
parents: 51268
diff changeset
461 }
8b243e2a3bc4 rust-index: a property to identify the Rust index as such
Georges Racinet <georges.racinet@octobus.net>
parents: 51268
diff changeset
462
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
463 });
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
464
51208
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
465 /// Take a (potentially) mmap'ed buffer, and return the underlying Python
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
466 /// buffer along with the Rust slice into said buffer. We need to keep the
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
467 /// Python buffer around, otherwise we'd get a dangling pointer once the buffer
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
468 /// is freed from Python's side.
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
469 ///
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
470 /// # Safety
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
471 ///
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
472 /// The caller must make sure that the buffer is kept around for at least as
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
473 /// long as the slice.
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
474 #[deny(unsafe_op_in_unsafe_fn)]
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
475 unsafe fn mmap_keeparound(
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
476 py: Python,
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
477 data: PyObject,
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
478 ) -> PyResult<(
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
479 PyBuffer,
51254
ca81cd96000a rust-index: add Sync bound to all relevant mmap-derived values
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51253
diff changeset
480 Box<dyn std::ops::Deref<Target = [u8]> + Send + Sync + 'static>,
51208
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
481 )> {
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
482 let buf = PyBuffer::get(py, &data)?;
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
483 let len = buf.item_count();
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
484
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
485 // Build a slice from the mmap'ed buffer data
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
486 let cbuf = buf.buf_ptr();
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
487 let bytes = if std::mem::size_of::<u8>() == buf.item_size()
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
488 && buf.is_c_contiguous()
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
489 && u8::is_compatible_format(buf.format())
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
490 {
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
491 unsafe { std::slice::from_raw_parts(cbuf as *const u8, len) }
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
492 } else {
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
493 return Err(PyErr::new::<ValueError, _>(
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
494 py,
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
495 "Nodemap data buffer has an invalid memory representation"
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
496 .to_string(),
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
497 ));
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
498 };
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
499
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
500 Ok((buf, Box::new(bytes)))
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
501 }
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
502
51213
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
503 fn py_tuple_to_revision_data_params(
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
504 py: Python,
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
505 tuple: PyTuple,
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
506 ) -> PyResult<RevisionDataParams> {
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
507 if tuple.len(py) < 8 {
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
508 // this is better than the panic promised by tup.get_item()
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
509 return Err(PyErr::new::<IndexError, _>(
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
510 py,
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
511 "tuple index out of range",
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
512 ));
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
513 }
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
514 let offset_or_flags: u64 = tuple.get_item(py, 0).extract(py)?;
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
515 let node_id = tuple
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
516 .get_item(py, 7)
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
517 .extract::<PyBytes>(py)?
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
518 .data(py)
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
519 .try_into()
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
520 .unwrap();
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
521 let flags = (offset_or_flags & 0xFFFF) as u16;
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
522 let data_offset = offset_or_flags >> 16;
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
523 Ok(RevisionDataParams {
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
524 flags,
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
525 data_offset,
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
526 data_compressed_length: tuple.get_item(py, 1).extract(py)?,
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
527 data_uncompressed_length: tuple.get_item(py, 2).extract(py)?,
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
528 data_delta_base: tuple.get_item(py, 3).extract(py)?,
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
529 link_rev: tuple.get_item(py, 4).extract(py)?,
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
530 parent_rev_1: tuple.get_item(py, 5).extract(py)?,
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
531 parent_rev_2: tuple.get_item(py, 6).extract(py)?,
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
532 node_id,
51226
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
533 ..Default::default()
51213
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
534 })
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
535 }
51226
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
536 fn revision_data_params_to_py_tuple(
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
537 py: Python,
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
538 params: RevisionDataParams,
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
539 ) -> PyTuple {
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
540 PyTuple::new(
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
541 py,
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
542 &[
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
543 params.data_offset.into_py_object(py).into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
544 params
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
545 .data_compressed_length
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
546 .into_py_object(py)
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
547 .into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
548 params
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
549 .data_uncompressed_length
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
550 .into_py_object(py)
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
551 .into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
552 params.data_delta_base.into_py_object(py).into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
553 params.link_rev.into_py_object(py).into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
554 params.parent_rev_1.into_py_object(py).into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
555 params.parent_rev_2.into_py_object(py).into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
556 PyBytes::new(py, &params.node_id)
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
557 .into_py_object(py)
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
558 .into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
559 params._sidedata_offset.into_py_object(py).into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
560 params
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
561 ._sidedata_compressed_length
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
562 .into_py_object(py)
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
563 .into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
564 params
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
565 .data_compression_mode
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
566 .into_py_object(py)
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
567 .into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
568 params
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
569 ._sidedata_compression_mode
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
570 .into_py_object(py)
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
571 .into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
572 params._rank.into_py_object(py).into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
573 ],
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
574 )
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
575 }
51213
65c9032e2e5a rust-index: synchronize append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51212
diff changeset
576
51233
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
577 struct PySnapshotsCache<'p> {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
578 py: Python<'p>,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
579 dict: PyDict,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
580 }
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
581
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
582 impl<'p> SnapshotsCache for PySnapshotsCache<'p> {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
583 fn insert_for(
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
584 &mut self,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
585 rev: BaseRevision,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
586 value: BaseRevision,
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
587 ) -> Result<(), RevlogError> {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
588 let pyvalue = value.into_py_object(self.py).into_object();
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
589 match self.dict.get_item(self.py, rev) {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
590 Some(obj) => obj
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
591 .extract::<PySet>(self.py)
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
592 .and_then(|set| set.add(self.py, pyvalue)),
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
593 None => PySet::new(self.py, vec![pyvalue])
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
594 .and_then(|set| self.dict.set_item(self.py, rev, set)),
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
595 }
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
596 .map_err(|_| {
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
597 RevlogError::Other(HgError::unsupported(
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
598 "Error in Python caches handling",
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
599 ))
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
600 })
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
601 }
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
602 }
9b06e7f32bc5 rust-index: add support for `find_snapshots`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51232
diff changeset
603
51275
f94c10334bcb rust-index: renamed `MixedIndex` as `Index`
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51274
diff changeset
604 impl Index {
f94c10334bcb rust-index: renamed `MixedIndex` as `Index`
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51274
diff changeset
605 fn new(py: Python, data: PyObject, header: u32) -> PyResult<Self> {
51211
6ec8387eb0be rust-index: pass data down to the Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51208
diff changeset
606 // Safety: we keep the buffer around inside the class as `index_mmap`
6ec8387eb0be rust-index: pass data down to the Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51208
diff changeset
607 let (buf, bytes) = unsafe { mmap_keeparound(py, data)? };
6ec8387eb0be rust-index: pass data down to the Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51208
diff changeset
608
44513
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
609 Self::create_instance(
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
610 py,
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
611 hg::index::Index::new(
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
612 bytes,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
613 IndexHeader::parse(&header.to_be_bytes())
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
614 .expect("default header is broken")
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
615 .unwrap(),
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
616 )
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
617 .map_err(|e| {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
618 revlog_error_with_msg(py, e.to_string().as_bytes())
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 51256
diff changeset
619 })?,
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
620 RefCell::new(None),
44519
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
621 RefCell::new(None),
44520
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
622 RefCell::new(None),
51211
6ec8387eb0be rust-index: pass data down to the Rust index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51208
diff changeset
623 RefCell::new(Some(buf)),
44513
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
624 )
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
625 }
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
626
51214
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51213
diff changeset
627 fn len(&self, py: Python) -> PyResult<usize> {
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51213
diff changeset
628 let rust_index_len = self.index(py).borrow().len();
51250
1b23aaf5eb7b rust-index: optimize find_gca_candidates() on less than 8 revisions
Georges Racinet <georges.racinet@octobus.net>
parents: 51246
diff changeset
629 Ok(rust_index_len)
51214
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51213
diff changeset
630 }
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51213
diff changeset
631
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
632 /// This is scaffolding at this point, but it could also become
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
633 /// a way to start a persistent nodemap or perform a
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
634 /// vacuum / repack operation
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
635 fn fill_nodemap(
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
636 &self,
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
637 py: Python,
51268
8dbd985733ff rust-cpython-revlog: renamed NodeTree import as CoreNodeTree
Georges Racinet <georges.racinet@octobus.net>
parents: 51267
diff changeset
638 nt: &mut CoreNodeTree,
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
639 ) -> PyResult<PyObject> {
51227
952e3cd7568f rust-index: using the Rust index in nodemap updating methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51226
diff changeset
640 let index = self.index(py).borrow();
51214
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51213
diff changeset
641 for r in 0..self.len(py)? {
50990
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50988
diff changeset
642 let rev = Revision(r as BaseRevision);
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
643 // in this case node() won't ever return None
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
644 nt.insert(&*index, index.node(rev).unwrap(), rev)
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
645 .map_err(|e| nodemap_error(py, e))?
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
646 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
647 Ok(py.None())
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
648 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
649
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
650 fn get_nodetree<'a>(
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
651 &'a self,
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
652 py: Python<'a>,
51268
8dbd985733ff rust-cpython-revlog: renamed NodeTree import as CoreNodeTree
Georges Racinet <georges.racinet@octobus.net>
parents: 51267
diff changeset
653 ) -> PyResult<&'a RefCell<Option<CoreNodeTree>>> {
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
654 if self.nt(py).borrow().is_none() {
51118
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50990
diff changeset
655 let readonly = Box::<Vec<_>>::default();
51268
8dbd985733ff rust-cpython-revlog: renamed NodeTree import as CoreNodeTree
Georges Racinet <georges.racinet@octobus.net>
parents: 51267
diff changeset
656 let mut nt = CoreNodeTree::load_bytes(readonly, 0);
44517
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
657 self.fill_nodemap(py, &mut nt)?;
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
658 self.nt(py).borrow_mut().replace(nt);
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
659 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
660 Ok(self.nt(py))
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
661 }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44516
diff changeset
662
44518
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
663 /// Returns the full nodemap bytes to be written as-is to disk
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
664 fn inner_nodemap_data_all(&self, py: Python) -> PyResult<PyBytes> {
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
665 let nodemap = self.get_nodetree(py)?.borrow_mut().take().unwrap();
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
666 let (readonly, bytes) = nodemap.into_readonly_and_added_bytes();
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
667
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
668 // If there's anything readonly, we need to build the data again from
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
669 // scratch
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
670 let bytes = if readonly.len() > 0 {
51268
8dbd985733ff rust-cpython-revlog: renamed NodeTree import as CoreNodeTree
Georges Racinet <georges.racinet@octobus.net>
parents: 51267
diff changeset
671 let mut nt = CoreNodeTree::load_bytes(Box::<Vec<_>>::default(), 0);
44518
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
672 self.fill_nodemap(py, &mut nt)?;
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
673
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
674 let (readonly, bytes) = nt.into_readonly_and_added_bytes();
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
675 assert_eq!(readonly.len(), 0);
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
676
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
677 bytes
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
678 } else {
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
679 bytes
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
680 };
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
681
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
682 let bytes = PyBytes::new(py, &bytes);
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
683 Ok(bytes)
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44517
diff changeset
684 }
44519
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
685
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
686 /// Returns the last saved docket along with the size of any changed data
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
687 /// (in number of blocks), and said data as bytes.
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
688 fn inner_nodemap_data_incremental(
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
689 &self,
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
690 py: Python,
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
691 ) -> PyResult<PyObject> {
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
692 let docket = self.docket(py).borrow();
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
693 let docket = match docket.as_ref() {
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
694 Some(d) => d,
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
695 None => return Ok(py.None()),
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
696 };
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
697
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
698 let node_tree = self.get_nodetree(py)?.borrow_mut().take().unwrap();
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
699 let masked_blocks = node_tree.masked_readonly_blocks();
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
700 let (_, data) = node_tree.into_readonly_and_added_bytes();
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
701 let changed = masked_blocks * std::mem::size_of::<Block>();
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
702
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
703 Ok((docket, changed, PyBytes::new(py, &data))
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
704 .to_py_object(py)
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
705 .into_object())
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44518
diff changeset
706 }
44520
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
707
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
708 /// Update the nodemap from the new (mmaped) data.
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
709 /// The docket is kept as a reference for later incremental calls.
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
710 fn inner_update_nodemap_data(
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
711 &self,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
712 py: Python,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
713 docket: PyObject,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
714 nm_data: PyObject,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
715 ) -> PyResult<PyObject> {
51208
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
716 // Safety: we keep the buffer around inside the class as `nodemap_mmap`
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51207
diff changeset
717 let (buf, bytes) = unsafe { mmap_keeparound(py, nm_data)? };
44520
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
718 let len = buf.item_count();
51207
8ade5e6cdb61 rust-mixed-index: rename variable to make the next change clearer
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51118
diff changeset
719 self.nodemap_mmap(py).borrow_mut().replace(buf);
44520
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
720
51268
8dbd985733ff rust-cpython-revlog: renamed NodeTree import as CoreNodeTree
Georges Racinet <georges.racinet@octobus.net>
parents: 51267
diff changeset
721 let mut nt = CoreNodeTree::load_bytes(bytes, len);
44520
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
722
50990
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50988
diff changeset
723 let data_tip = docket
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50988
diff changeset
724 .getattr(py, "tip_rev")?
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50988
diff changeset
725 .extract::<BaseRevision>(py)?
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50988
diff changeset
726 .into();
44520
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
727 self.docket(py).borrow_mut().replace(docket.clone_ref(py));
51227
952e3cd7568f rust-index: using the Rust index in nodemap updating methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51226
diff changeset
728 let idx = self.index(py).borrow();
50988
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49987
diff changeset
729 let data_tip = idx.check_revision(data_tip).ok_or_else(|| {
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49987
diff changeset
730 nodemap_error(py, NodeMapError::RevisionNotInIndex(data_tip))
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49987
diff changeset
731 })?;
44520
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
732 let current_tip = idx.len();
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
733
50990
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50988
diff changeset
734 for r in (data_tip.0 + 1)..current_tip as BaseRevision {
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50988
diff changeset
735 let rev = Revision(r);
44520
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
736 // in this case node() won't ever return None
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
737 nt.insert(&*idx, idx.node(rev).unwrap(), rev)
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
738 .map_err(|e| nodemap_error(py, e))?
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
739 }
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
740
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
741 *self.nt(py).borrow_mut() = Some(nt);
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
742
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
743 Ok(py.None())
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44519
diff changeset
744 }
51226
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
745
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
746 fn inner_getitem(&self, py: Python, key: PyObject) -> PyResult<PyObject> {
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
747 let idx = self.index(py).borrow();
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
748 Ok(match key.extract::<BaseRevision>(py) {
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
749 Ok(key_as_int) => {
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
750 let entry_params = if key_as_int == NULL_REVISION.0 {
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
751 RevisionDataParams::default()
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
752 } else {
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
753 let rev = UncheckedRevision(key_as_int);
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
754 match idx.entry_as_params(rev) {
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
755 Some(e) => e,
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
756 None => {
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
757 return Err(PyErr::new::<IndexError, _>(
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
758 py,
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
759 "revlog index out of range",
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
760 ));
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
761 }
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
762 }
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
763 };
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
764 revision_data_params_to_py_tuple(py, entry_params)
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
765 .into_object()
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
766 }
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
767 _ => self.get_rev(py, key.extract::<PyBytes>(py)?)?.map_or_else(
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
768 || py.None(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
769 |py_rev| py_rev.into_py_object(py).into_object(),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
770 ),
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
771 })
002b49905aac rust-index: implementation of __getitem__
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51225
diff changeset
772 }
51236
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
773
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
774 fn inner_headrevs(&self, py: Python) -> PyResult<PyObject> {
51255
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51254
diff changeset
775 let index = &*self.index(py).borrow();
51236
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
776 let as_vec: Vec<PyObject> = index
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
777 .head_revs()
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
778 .map_err(|e| graph_error(py, e))?
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
779 .iter()
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
780 .map(|r| PyRevision::from(*r).into_py_object(py).into_object())
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
781 .collect();
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
782 Ok(PyList::new(py, &as_vec).into_object())
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
783 }
51237
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51236
diff changeset
784
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51236
diff changeset
785 fn inner_headrevsfiltered(
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51236
diff changeset
786 &self,
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51236
diff changeset
787 py: Python,
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51236
diff changeset
788 filtered_revs: &PyObject,
51238
898674a4dbc7 rust-index: headrevsfiltered() returning Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51237
diff changeset
789 ) -> PyResult<PyObject> {
51237
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51236
diff changeset
790 let index = &mut *self.index(py).borrow_mut();
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51236
diff changeset
791 let filtered_revs = rev_pyiter_collect(py, filtered_revs, index)?;
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51236
diff changeset
792
51238
898674a4dbc7 rust-index: headrevsfiltered() returning Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51237
diff changeset
793 let as_vec: Vec<PyObject> = index
51237
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51236
diff changeset
794 .head_revs_filtered(&filtered_revs)
51238
898674a4dbc7 rust-index: headrevsfiltered() returning Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51237
diff changeset
795 .map_err(|e| graph_error(py, e))?
898674a4dbc7 rust-index: headrevsfiltered() returning Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51237
diff changeset
796 .iter()
898674a4dbc7 rust-index: headrevsfiltered() returning Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51237
diff changeset
797 .map(|r| PyRevision::from(*r).into_py_object(py).into_object())
898674a4dbc7 rust-index: headrevsfiltered() returning Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51237
diff changeset
798 .collect();
898674a4dbc7 rust-index: headrevsfiltered() returning Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51237
diff changeset
799 Ok(PyList::new(py, &as_vec).into_object())
51237
9f876765cbe2 rust-index: add support for `headrevsfiltered`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51236
diff changeset
800 }
51239
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
801
51246
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
802 fn inner_ancestors(
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
803 &self,
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
804 py: Python,
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
805 py_revs: &PyTuple,
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
806 ) -> PyResult<PyObject> {
51255
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51254
diff changeset
807 let index = &*self.index(py).borrow();
51246
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
808 let revs: Vec<_> = rev_pyiter_collect(py, py_revs.as_object(), index)?;
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
809 let as_vec: Vec<_> = index
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
810 .ancestors(&revs)
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
811 .map_err(|e| graph_error(py, e))?
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
812 .iter()
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
813 .map(|r| PyRevision::from(*r).into_py_object(py).into_object())
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
814 .collect();
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
815 Ok(PyList::new(py, &as_vec).into_object())
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
816 }
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
817
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
818 fn inner_commonancestorsheads(
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
819 &self,
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
820 py: Python,
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
821 py_revs: &PyTuple,
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
822 ) -> PyResult<PyObject> {
51255
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51254
diff changeset
823 let index = &*self.index(py).borrow();
51246
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
824 let revs: Vec<_> = rev_pyiter_collect(py, py_revs.as_object(), index)?;
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
825 let as_vec: Vec<_> = index
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
826 .common_ancestor_heads(&revs)
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
827 .map_err(|e| graph_error(py, e))?
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
828 .iter()
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
829 .map(|r| PyRevision::from(*r).into_py_object(py).into_object())
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
830 .collect();
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
831 Ok(PyList::new(py, &as_vec).into_object())
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
832 }
89ce6a49bfeb rust-index: implement common_ancestors_heads() and ancestors()
Georges Racinet <georges.racinet@octobus.net>
parents: 51243
diff changeset
833
51241
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
834 fn inner_computephasesmapsets(
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
835 &self,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
836 py: Python,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
837 py_roots: PyDict,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
838 ) -> PyResult<PyObject> {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
839 let index = &*self.index(py).borrow();
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
840 let opt = self.get_nodetree(py)?.borrow();
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
841 let nt = opt.as_ref().unwrap();
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
842 let roots: Result<HashMap<Phase, Vec<Revision>>, PyErr> = py_roots
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
843 .items_list(py)
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
844 .iter(py)
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
845 .map(|r| {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
846 let phase = r.get_item(py, 0)?;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
847 let nodes = r.get_item(py, 1)?;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
848 // Transform the nodes from Python to revs here since we
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
849 // have access to the nodemap
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
850 let revs: Result<_, _> = nodes
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
851 .iter(py)?
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
852 .map(|node| match node?.extract::<PyBytes>(py) {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
853 Ok(py_bytes) => {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
854 let node = node_from_py_bytes(py, &py_bytes)?;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
855 nt.find_bin(index, node.into())
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
856 .map_err(|e| nodemap_error(py, e))?
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
857 .ok_or_else(|| revlog_error(py))
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
858 }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
859 Err(e) => Err(e),
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
860 })
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
861 .collect();
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
862 let phase = Phase::try_from(phase.extract::<usize>(py)?)
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
863 .map_err(|_| revlog_error(py));
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
864 Ok((phase?, revs?))
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
865 })
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
866 .collect();
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
867 let (len, phase_maps) = index
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
868 .compute_phases_map_sets(roots?)
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
869 .map_err(|e| graph_error(py, e))?;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
870
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
871 // Ugly hack, but temporary
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
872 const IDX_TO_PHASE_NUM: [usize; 4] = [1, 2, 32, 96];
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
873 let py_phase_maps = PyDict::new(py);
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
874 for (idx, roots) in phase_maps.iter().enumerate() {
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
875 let phase_num = IDX_TO_PHASE_NUM[idx].into_py_object(py);
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
876 // OPTIM too bad we have to collect here. At least, we could
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
877 // reuse the same Vec and allocate it with capacity at
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
878 // max(len(phase_maps)
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
879 let roots_vec: Vec<PyInt> = roots
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
880 .iter()
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
881 .map(|r| PyRevision::from(*r).into_py_object(py))
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
882 .collect();
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
883 py_phase_maps.set_item(
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
884 py,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
885 phase_num,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
886 PySet::new(py, roots_vec)?,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
887 )?;
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
888 }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
889 Ok(PyTuple::new(
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
890 py,
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
891 &[
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
892 len.into_py_object(py).into_object(),
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
893 py_phase_maps.into_object(),
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
894 ],
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
895 )
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
896 .into_object())
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
897 }
c817d9f626d3 rust-index: add support for `computephasesmapsets`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51240
diff changeset
898
51239
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
899 fn inner_slicechunktodensity(
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
900 &self,
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
901 py: Python,
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
902 revs: PyObject,
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
903 target_density: f64,
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
904 min_gap_size: usize,
51240
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
905 ) -> PyResult<PyObject> {
51255
59183a19954e rust-index: use interior mutability in head revs and caches
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51254
diff changeset
906 let index = &*self.index(py).borrow();
51239
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
907 let revs: Vec<_> = rev_pyiter_collect(py, &revs, index)?;
51240
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
908 let as_nested_vec =
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
909 index.slice_chunk_to_density(&revs, target_density, min_gap_size);
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
910 let mut res = Vec::with_capacity(as_nested_vec.len());
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
911 let mut py_chunk = Vec::new();
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
912 for chunk in as_nested_vec {
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
913 py_chunk.clear();
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
914 py_chunk.reserve_exact(chunk.len());
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
915 for rev in chunk {
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
916 py_chunk.push(
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
917 PyRevision::from(rev).into_py_object(py).into_object(),
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
918 );
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
919 }
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
920 res.push(PyList::new(py, &py_chunk).into_object());
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
921 }
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
922 // This is just to do the same as C, not sure why it does this
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
923 if res.len() == 1 {
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
924 Ok(PyTuple::new(py, &res).into_object())
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
925 } else {
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
926 Ok(PyList::new(py, &res).into_object())
8cb31833b486 rust-index: slicechunktodensity returns Rust result
Georges Racinet <georges.racinet@octobus.net>
parents: 51239
diff changeset
927 }
51239
0112803e6c01 rust-index: add support for `_slicechunktodensity`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51238
diff changeset
928 }
51243
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
929
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
930 fn inner_reachableroots2(
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
931 &self,
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
932 py: Python,
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
933 min_root: UncheckedRevision,
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
934 heads: PyObject,
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
935 roots: PyObject,
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
936 include_path: bool,
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
937 ) -> PyResult<PyObject> {
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
938 let index = &*self.index(py).borrow();
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
939 let heads = rev_pyiter_collect_or_else(py, &heads, index, |_rev| {
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
940 PyErr::new::<IndexError, _>(py, "head out of range")
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
941 })?;
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
942 let roots: Result<_, _> = roots
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
943 .iter(py)?
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
944 .map(|r| {
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
945 r.and_then(|o| match o.extract::<PyRevision>(py) {
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
946 Ok(r) => Ok(UncheckedRevision(r.0)),
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
947 Err(e) => Err(e),
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
948 })
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
949 })
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
950 .collect();
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
951 let as_set = index
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
952 .reachable_roots(min_root, heads, roots?, include_path)
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
953 .map_err(|e| graph_error(py, e))?;
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
954 let as_vec: Vec<PyObject> = as_set
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
955 .iter()
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
956 .map(|r| PyRevision::from(*r).into_py_object(py).into_object())
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
957 .collect();
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
958 Ok(PyList::new(py, &as_vec).into_object())
fc05dd74e907 rust-index: add support for `reachableroots2`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51241
diff changeset
959 }
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
960 }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
961
51270
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
962 py_class!(pub class NodeTree |py| {
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
963 data nt: RefCell<CoreNodeTree>;
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
964 data index: RefCell<UnsafePyLeaked<PySharedIndex>>;
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
965
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
966 def __new__(_cls, index: PyObject) -> PyResult<NodeTree> {
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
967 let index = py_rust_index_to_graph(py, index)?;
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
968 let nt = CoreNodeTree::default(); // in-RAM, fully mutable
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
969 Self::create_instance(py, RefCell::new(nt), RefCell::new(index))
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
970 }
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
971
51272
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
972 /// Tell whether the NodeTree is still valid
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
973 ///
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
974 /// In case of mutation of the index, the given results are not
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
975 /// guaranteed to be correct, and in fact, the methods borrowing
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
976 /// the inner index would fail because of `PySharedRef` poisoning
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
977 /// (generation-based guard), same as iterating on a `dict` that has
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
978 /// been meanwhile mutated.
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
979 def is_invalidated(&self) -> PyResult<bool> {
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
980 let leaked = self.index(py).borrow();
51276
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51275
diff changeset
981 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51272
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
982 let result = unsafe { leaked.try_borrow(py) };
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
983 // two cases for result to be an error:
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
984 // - the index has previously been mutably borrowed
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
985 // - there is currently a mutable borrow
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
986 // in both cases this amounts for previous results related to
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
987 // the index to still be valid.
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
988 Ok(result.is_err())
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
989 }
0409bd6ba663 rust-revlog: add invalidation detection to `NodeTree` class
Georges Racinet <georges.racinet@octobus.net>
parents: 51271
diff changeset
990
51270
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
991 def insert(&self, rev: PyRevision) -> PyResult<PyObject> {
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
992 let leaked = self.index(py).borrow();
51276
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51275
diff changeset
993 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51270
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
994 let index = &*unsafe { leaked.try_borrow(py)? };
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
995
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
996 let rev = UncheckedRevision(rev.0);
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
997 let rev = index
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
998 .check_revision(rev)
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
999 .ok_or_else(|| rev_not_in_index(py, rev))?;
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1000 if rev == NULL_REVISION {
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1001 return Err(rev_not_in_index(py, rev.into()))
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1002 }
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1003
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1004 let entry = index.inner.get_entry(rev).unwrap();
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1005 let mut nt = self.nt(py).borrow_mut();
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1006 nt.insert(index, entry.hash(), rev).map_err(|e| nodemap_error(py, e))?;
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1007
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1008 Ok(py.None())
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1009 }
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1010
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1011 /// Lookup by node hex prefix in the NodeTree, returning revision number.
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1012 ///
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1013 /// This is not part of the classical NodeTree API, but is good enough
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1014 /// for unit testing, as in `test-rust-revlog.py`.
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1015 def prefix_rev_lookup(
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1016 &self,
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1017 node_prefix: PyBytes
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1018 ) -> PyResult<Option<PyRevision>> {
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1019 let prefix = NodePrefix::from_hex(node_prefix.data(py))
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1020 .map_err(|_| PyErr::new::<ValueError, _>(
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1021 py,
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1022 format!("Invalid node or prefix {:?}",
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1023 node_prefix.as_object()))
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1024 )?;
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1025
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1026 let nt = self.nt(py).borrow();
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1027 let leaked = self.index(py).borrow();
51276
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51275
diff changeset
1028 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51270
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1029 let index = &*unsafe { leaked.try_borrow(py)? };
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1030
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1031 Ok(nt.find_bin(index, prefix)
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1032 .map_err(|e| nodemap_error(py, e))?
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1033 .map(|r| r.into())
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1034 )
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1035 }
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1036
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1037 def shortest(&self, node: PyBytes) -> PyResult<usize> {
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1038 let nt = self.nt(py).borrow();
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1039 let leaked = self.index(py).borrow();
51276
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51275
diff changeset
1040 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51270
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1041 let idx = &*unsafe { leaked.try_borrow(py)? };
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1042 match nt.unique_prefix_len_node(idx, &node_from_py_bytes(py, &node)?)
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1043 {
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1044 Ok(Some(l)) => Ok(l),
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1045 Ok(None) => Err(revlog_error(py)),
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1046 Err(e) => Err(nodemap_error(py, e)),
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1047 }
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1048 }
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1049 });
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1050
44516
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1051 fn revlog_error(py: Python) -> PyErr {
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1052 match py
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1053 .import("mercurial.error")
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1054 .and_then(|m| m.get(py, "RevlogError"))
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1055 {
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1056 Err(e) => e,
47316
33e7508b0ae9 hg-cpython: fix new occuring TypeError
Rapha?l Gom?s <rgomes@octobus.net>
parents: 47279
diff changeset
1057 Ok(cls) => PyErr::from_instance(
33e7508b0ae9 hg-cpython: fix new occuring TypeError
Rapha?l Gom?s <rgomes@octobus.net>
parents: 47279
diff changeset
1058 py,
33e7508b0ae9 hg-cpython: fix new occuring TypeError
Rapha?l Gom?s <rgomes@octobus.net>
parents: 47279
diff changeset
1059 cls.call(py, (py.None(),), None).ok().into_py_object(py),
33e7508b0ae9 hg-cpython: fix new occuring TypeError
Rapha?l Gom?s <rgomes@octobus.net>
parents: 47279
diff changeset
1060 ),
44516
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1061 }
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1062 }
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1063
51252
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1064 fn revlog_error_with_msg(py: Python, msg: &[u8]) -> PyErr {
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1065 match py
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1066 .import("mercurial.error")
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1067 .and_then(|m| m.get(py, "RevlogError"))
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1068 {
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1069 Err(e) => e,
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1070 Ok(cls) => PyErr::from_instance(
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1071 py,
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1072 cls.call(py, (PyBytes::new(py, msg),), None)
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1073 .ok()
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1074 .into_py_object(py),
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1075 ),
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1076 }
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1077 }
5807e3a8865e rust-python-index: don't panic on a corrupted index when calling from Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51250
diff changeset
1078
51236
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
1079 fn graph_error(py: Python, _err: hg::GraphError) -> PyErr {
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
1080 // ParentOutOfRange is currently the only alternative
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
1081 // in `hg::GraphError`. The C index always raises this simple ValueError.
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
1082 PyErr::new::<ValueError, _>(py, "parent out of range")
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
1083 }
a7bba7df9189 rust-index: implement headrevs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51235
diff changeset
1084
51220
44fbb7dfb563 rust-index: renamed nodemap error function for rev not in index
Georges Racinet <georges.racinet@octobus.net>
parents: 51219
diff changeset
1085 fn nodemap_rev_not_in_index(py: Python, rev: UncheckedRevision) -> PyErr {
44516
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1086 PyErr::new::<ValueError, _>(
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1087 py,
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1088 format!(
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1089 "Inconsistency: Revision {} found in nodemap \
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1090 is not in revlog index",
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1091 rev
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1092 ),
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1093 )
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1094 }
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1095
51221
bc4d83047c6c rust-index: helper for revision not in index not involving nodemap
Georges Racinet <georges.racinet@octobus.net>
parents: 51220
diff changeset
1096 fn rev_not_in_index(py: Python, rev: UncheckedRevision) -> PyErr {
bc4d83047c6c rust-index: helper for revision not in index not involving nodemap
Georges Racinet <georges.racinet@octobus.net>
parents: 51220
diff changeset
1097 PyErr::new::<ValueError, _>(
bc4d83047c6c rust-index: helper for revision not in index not involving nodemap
Georges Racinet <georges.racinet@octobus.net>
parents: 51220
diff changeset
1098 py,
bc4d83047c6c rust-index: helper for revision not in index not involving nodemap
Georges Racinet <georges.racinet@octobus.net>
parents: 51220
diff changeset
1099 format!("revlog index out of range: {}", rev),
bc4d83047c6c rust-index: helper for revision not in index not involving nodemap
Georges Racinet <georges.racinet@octobus.net>
parents: 51220
diff changeset
1100 )
bc4d83047c6c rust-index: helper for revision not in index not involving nodemap
Georges Racinet <georges.racinet@octobus.net>
parents: 51220
diff changeset
1101 }
bc4d83047c6c rust-index: helper for revision not in index not involving nodemap
Georges Racinet <georges.racinet@octobus.net>
parents: 51220
diff changeset
1102
44516
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1103 /// Standard treatment of NodeMapError
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1104 fn nodemap_error(py: Python, err: NodeMapError) -> PyErr {
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1105 match err {
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1106 NodeMapError::MultipleResults => revlog_error(py),
51220
44fbb7dfb563 rust-index: renamed nodemap error function for rev not in index
Georges Racinet <georges.racinet@octobus.net>
parents: 51219
diff changeset
1107 NodeMapError::RevisionNotInIndex(r) => nodemap_rev_not_in_index(py, r),
44516
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1108 }
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1109 }
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44513
diff changeset
1110
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1111 /// Create the module, with __package__ given from parent
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1112 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1113 let dotted_name = &format!("{}.revlog", package);
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1114 let m = PyModule::new(py, dotted_name)?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1115 m.add(py, "__package__", package)?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1116 m.add(py, "__doc__", "RevLog - Rust implementations")?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1117
51275
f94c10334bcb rust-index: renamed `MixedIndex` as `Index`
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51274
diff changeset
1118 m.add_class::<Index>(py)?;
51270
2966b88d4531 rust-revlog: bare minimal NodeTree exposition
Georges Racinet <georges.racinet@octobus.net>
parents: 51269
diff changeset
1119 m.add_class::<NodeTree>(py)?;
43966
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1120
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1121 let sys = PyModule::import(py, "sys")?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1122 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1123 sys_modules.set_item(py, dotted_name, &m)?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1124
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1125 Ok(m)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43951
diff changeset
1126 }