annotate rust/hg-pyo3/src/revlog/mod.rs @ 52794:5ad4ed71fbe0

rust-pyo3: helper to build Python lists of revisions It really seems that the PyO3 bindings will perform less copying than their rust-cpython counterparts: instead of building a vector with the results (first copy) then passing a reference to `PyList::new`, (that therefore would have to copy again), we can pass an iterator of the elements, as long as they have a single type (`PyRevision`) in this case.
author Georges Racinet <georges.racinet@cloudcrane.io>
date Wed, 25 Dec 2024 19:05:27 +0100
parents 6a70e4931773
children adf91dfe6c04
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
52775
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
1 // revlog.rs
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
2 //
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
3 // Copyright 2019-2020 Georges Racinet <georges.racinet@octobus.net>
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
4 // 2020-2024 Raphaël Gomès <raphael.gomes@octobus.net>
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
5 // 2024 Georges Racinet <georges.racinet@cloudcrane.io>
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
6 //
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
7 // This software may be used and distributed according to the terms of the
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
8 // GNU General Public License version 2 or any later version.
52787
e5f89bd1a5ee rust-pyo3-revlog: _index___len__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52786
diff changeset
9 #![allow(non_snake_case)]
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
10 use pyo3::buffer::PyBuffer;
52791
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
11 use pyo3::conversion::IntoPyObject;
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
12 use pyo3::exceptions::PyIndexError;
52775
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
13 use pyo3::prelude::*;
52789
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
14 use pyo3::types::{PyBytes, PyBytesMethods, PyList, PyTuple};
52792
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
15 use pyo3_sharedref::{PyShareable, SharedByPyObject};
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
16
52786
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
17 use std::sync::{
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
18 atomic::{AtomicUsize, Ordering},
52788
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
19 RwLock, RwLockReadGuard, RwLockWriteGuard,
52786
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
20 };
52775
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
21
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
22 use hg::{
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
23 revlog::{
52791
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
24 index::{Index, RevisionDataParams},
52786
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
25 inner_revlog::InnerRevlog as CoreInnerRevlog,
52789
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
26 nodemap::{NodeMap, NodeMapError, NodeTree as CoreNodeTree},
52786
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
27 options::RevlogOpenOptions,
52782
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
28 RevlogIndex, RevlogType,
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
29 },
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
30 utils::files::get_path_from_bytes,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
31 vfs::FnCacheVfs,
52791
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
32 BaseRevision, Revision, UncheckedRevision, NULL_REVISION,
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
33 };
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
34
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
35 use crate::{
52784
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
36 exceptions::{
52794
5ad4ed71fbe0 rust-pyo3: helper to build Python lists of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52793
diff changeset
37 map_lock_error, map_try_lock_error, nodemap_error, rev_not_in_index,
5ad4ed71fbe0 rust-pyo3: helper to build Python lists of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52793
diff changeset
38 revlog_error_bare, revlog_error_from_msg,
52784
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
39 },
52786
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
40 node::{node_from_py_bytes, node_prefix_from_py_bytes, py_node_for_rev},
52792
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
41 revision::{check_revision, PyRevision},
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
42 store::PyFnCache,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
43 util::{new_submodule, take_buffer_with_slice},
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
44 };
52775
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
45
52778
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52775
diff changeset
46 mod config;
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
47 use config::*;
52789
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
48 mod index;
52791
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
49 use index::{
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
50 py_tuple_to_revision_data_params, revision_data_params_to_py_tuple,
52792
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
51 PySharedIndex,
52791
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
52 };
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
53
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
54 #[pyclass]
52793
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
55 struct ReadingContextManager {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
56 inner_revlog: Py<InnerRevlog>,
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
57 }
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
58
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
59 #[pymethods]
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
60 impl ReadingContextManager {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
61 fn __enter__(slf: PyRef<'_, Self>) -> PyResult<()> {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
62 let inner_bound = slf.inner_revlog.bind(slf.py());
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
63 let shareable = &inner_bound.borrow().irl;
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
64 // Safety: the owner is correct and we won't use `share()` anyway
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
65 let core_irl =
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
66 unsafe { shareable.borrow_with_owner(inner_bound) }.read();
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
67 core_irl
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
68 .enter_reading_context()
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
69 .map_err(revlog_error_from_msg)
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
70 .inspect_err(|_e| {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
71 // `__exit__` is not called from Python if `__enter__` fails
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
72 core_irl.exit_reading_context();
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
73 })
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
74 }
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
75
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
76 #[pyo3(signature = (*_args))]
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
77 fn __exit__(slf: PyRef<'_, Self>, _args: &Bound<'_, PyTuple>) {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
78 let inner_bound = slf.inner_revlog.bind(slf.py());
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
79 let shareable = &inner_bound.borrow().irl;
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
80 // Safety: the owner is correct and we won't use `share()` anyway
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
81 let core_irl_ref = unsafe { shareable.borrow_with_owner(inner_bound) };
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
82 core_irl_ref.read().exit_reading_context();
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
83 }
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
84 }
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
85
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
86 #[pyclass]
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
87 #[allow(dead_code)]
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
88 struct InnerRevlog {
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
89 irl: PyShareable<CoreInnerRevlog>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
90 nt: RwLock<Option<CoreNodeTree>>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
91 docket: Option<PyObject>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
92 // Holds a reference to the mmap'ed persistent nodemap data
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
93 nodemap_mmap: Option<PyBuffer<u8>>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
94 // Holds a reference to the mmap'ed persistent index data
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
95 index_mmap: Option<PyBuffer<u8>>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
96 revision_cache: Option<PyObject>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
97 head_revs_py_list: Option<Py<PyList>>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
98 head_node_ids_py_list: Option<Py<PyList>>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
99 use_persistent_nodemap: bool,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
100 nodemap_queries: AtomicUsize,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
101 }
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
102
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
103 #[pymethods]
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
104 impl InnerRevlog {
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
105 #[new]
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
106 // The Python side has authority on this signature.
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
107 #[allow(clippy::too_many_arguments)]
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
108 fn new(
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
109 vfs_base: &Bound<'_, PyBytes>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
110 fncache: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
111 vfs_is_readonly: bool,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
112 index_data: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
113 index_file: &Bound<'_, PyBytes>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
114 data_file: &Bound<'_, PyBytes>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
115 sidedata_file: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
116 inline: bool,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
117 data_config: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
118 delta_config: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
119 feature_config: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
120 chunk_cache: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
121 default_compression_header: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
122 revlog_type: usize,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
123 use_persistent_nodemap: bool,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
124 ) -> PyResult<Self> {
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
125 // Let clippy accept the unused arguments. This is a bit better than
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
126 // a blank `allow` directive
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
127 let _ = sidedata_file;
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
128 let _ = chunk_cache;
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
129 let _ = default_compression_header;
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
130
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
131 let index_file = get_path_from_bytes(index_file.as_bytes()).to_owned();
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
132 let data_file = get_path_from_bytes(data_file.as_bytes()).to_owned();
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
133 let revlog_type = RevlogType::try_from(revlog_type)
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
134 .map_err(revlog_error_from_msg)?;
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
135 let data_config = extract_data_config(data_config, revlog_type)?;
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
136 let delta_config = extract_delta_config(delta_config, revlog_type)?;
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
137 let feature_config =
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
138 extract_feature_config(feature_config, revlog_type)?;
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
139 let options = RevlogOpenOptions::new(
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
140 inline,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
141 data_config,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
142 delta_config,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
143 feature_config,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
144 );
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
145
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
146 // Safety: we keep the buffer around inside the returned instance as
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
147 // `index_mmap`
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
148 let (buf, bytes) = unsafe { take_buffer_with_slice(index_data)? };
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
149 let index = Index::new(bytes, options.index_header())
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
150 .map_err(revlog_error_from_msg)?;
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
151
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
152 let base = get_path_from_bytes(vfs_base.as_bytes()).to_owned();
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
153 let core = CoreInnerRevlog::new(
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
154 Box::new(FnCacheVfs::new(
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
155 base,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
156 vfs_is_readonly,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
157 Box::new(PyFnCache::new(fncache.clone().unbind())),
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
158 )),
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
159 index,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
160 index_file,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
161 data_file,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
162 data_config,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
163 delta_config,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
164 feature_config,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
165 );
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
166 Ok(Self {
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
167 irl: core.into(),
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
168 nt: None.into(),
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
169 docket: None,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
170 nodemap_mmap: None,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
171 index_mmap: buf.into(),
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
172 head_revs_py_list: None,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
173 head_node_ids_py_list: None,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
174 revision_cache: None,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
175 use_persistent_nodemap,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
176 nodemap_queries: AtomicUsize::new(0),
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
177 })
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
178 }
52786
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
179
52793
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
180 fn reading(slf: &Bound<'_, Self>) -> PyResult<ReadingContextManager> {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
181 Ok(ReadingContextManager {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
182 inner_revlog: slf.clone().unbind(),
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
183 })
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
184 }
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
185
52786
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
186 //
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
187 // -- forwarded index methods --
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
188 //
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
189
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
190 fn _index_get_rev(
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
191 slf: &Bound<'_, Self>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
192 node: &Bound<'_, PyBytes>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
193 ) -> PyResult<Option<PyRevision>> {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
194 let node = node_from_py_bytes(node)?;
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
195
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
196 // Do not rewrite this with `Self::with_index_nt_read`: it makes
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
197 // inconditionally a volatile nodetree, and that is not the intent
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
198 // here: the code below specifically avoids that.
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
199 Self::with_core_read(slf, |self_ref, irl| {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
200 let idx = &irl.index;
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
201
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
202 let prev_queries =
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
203 self_ref.nodemap_queries.fetch_add(1, Ordering::Relaxed);
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
204 // Filelogs have no persistent nodemaps and are often small,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
205 // use a brute force lookup from the end
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
206 // backwards. If there is a very large filelog
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
207 // (automation file that changes every
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
208 // commit etc.), it also seems to work quite well for
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
209 // all measured purposes so far.
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
210 if !self_ref.use_persistent_nodemap && prev_queries <= 3 {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
211 return Ok(idx
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
212 .rev_from_node_no_persistent_nodemap(node.into())
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
213 .ok()
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
214 .map(Into::into));
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
215 }
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
216
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
217 let opt =
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
218 self_ref.get_nodetree(idx)?.read().map_err(map_lock_error)?;
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
219 let nt = opt.as_ref().expect("nodetree should be set");
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
220
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
221 let rust_rev =
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
222 nt.find_bin(idx, node.into()).map_err(nodemap_error)?;
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
223 Ok(rust_rev.map(Into::into))
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
224 })
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
225 }
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
226
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
227 /// same as `_index_get_rev()` but raises a bare `error.RevlogError` if
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
228 /// node is not found.
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
229 ///
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
230 /// No need to repeat `node` in the exception, `mercurial/revlog.py`
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
231 /// will catch and rewrap with it
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
232 fn _index_rev(
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
233 slf: &Bound<'_, Self>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
234 node: &Bound<'_, PyBytes>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
235 ) -> PyResult<PyRevision> {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
236 Self::_index_get_rev(slf, node)?.ok_or_else(revlog_error_bare)
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
237 }
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
238
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
239 /// return True if the node exist in the index
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
240 fn _index_has_node(
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
241 slf: &Bound<'_, Self>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
242 node: &Bound<'_, PyBytes>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
243 ) -> PyResult<bool> {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
244 Self::_index_get_rev(slf, node).map(|opt| opt.is_some())
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
245 }
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
246
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
247 /// find length of shortest hex nodeid of a binary ID
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
248 fn _index_shortest(
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
249 slf: &Bound<'_, Self>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
250 node: &Bound<'_, PyBytes>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
251 ) -> PyResult<usize> {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
252 Self::with_index_nt_read(slf, |idx, nt| {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
253 match nt.unique_prefix_len_node(idx, &node_from_py_bytes(node)?) {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
254 Ok(Some(l)) => Ok(l),
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
255 Ok(None) => Err(revlog_error_bare()),
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
256 Err(e) => Err(nodemap_error(e)),
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
257 }
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
258 })
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
259 }
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
260
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
261 fn _index_partialmatch<'py>(
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
262 slf: &Bound<'py, Self>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
263 node: &Bound<'py, PyBytes>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
264 ) -> PyResult<Option<Bound<'py, PyBytes>>> {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
265 Self::with_index_nt_read(slf, |idx, nt| {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
266 Ok(nt
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
267 .find_bin(idx, node_prefix_from_py_bytes(node)?)
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
268 .map_err(nodemap_error)?
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
269 .map(|rev| py_node_for_rev(slf.py(), idx, rev)))
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
270 })
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
271 }
52787
e5f89bd1a5ee rust-pyo3-revlog: _index___len__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52786
diff changeset
272
52789
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
273 /// append an index entry
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
274 fn _index_append(
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
275 slf: &Bound<'_, Self>,
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
276 tup: &Bound<'_, PyTuple>,
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
277 ) -> PyResult<()> {
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
278 // no need to check length: in PyO3 tup.get_item() does return
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
279 // proper errors
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
280 let node_bytes = tup.get_item(7)?.extract()?;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
281 let node = node_from_py_bytes(&node_bytes)?;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
282
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
283 Self::with_index_nt_write(slf, |idx, nt| {
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
284 let rev = idx.len() as BaseRevision;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
285 // This is ok since we will immediately add the revision to the
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
286 // index
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
287 let rev = Revision(rev);
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
288 idx.append(py_tuple_to_revision_data_params(tup)?)
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
289 .map_err(revlog_error_from_msg)?;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
290
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
291 nt.insert(idx, &node, rev).map_err(nodemap_error)?;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
292 Ok(())
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
293 })
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
294 }
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
295
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
296 /// Removes one or several entries from the index.
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
297 ///
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
298 /// Historically, on the Mercurial revlog index, `__delitem__` has always
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
299 /// been both for `del idx[r1]` and `del idx[r1:r2]`. In both cases,
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
300 /// all entries starting from `r1` are removed anyway.
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
301 fn _index___delitem__(
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
302 slf: &Bound<'_, Self>,
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
303 arg: &Bound<'_, PyAny>,
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
304 ) -> PyResult<()> {
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
305 let start = if let Ok(rev) = arg.extract() {
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
306 UncheckedRevision(rev)
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
307 } else {
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
308 // here we could downcast to `PySlice` and use `indices()`, *but*
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
309 // the rust-cpython based version could not do that, and
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
310 // `indices()` does some resolving that makes it not equivalent,
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
311 // e.g., `idx[-1::]` has `start=0`. As we are currently in
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
312 // transition, we keep it the old way (hoping it was consistent
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
313 // with the C index).
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
314 let start = arg.getattr("start")?;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
315 UncheckedRevision(start.extract()?)
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
316 };
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
317
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
318 Self::with_index_nt_write(slf, |idx, nt| {
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
319 // In the case of a slice, the check is possibly already done by
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
320 // `slice.indices`, which is itself an FFI wrapper for CPython's
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
321 // `PySlice_GetIndicesEx`
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
322 // (Python integration tests will tell us)
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
323 let start = idx.check_revision(start).ok_or_else(|| {
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
324 nodemap_error(NodeMapError::RevisionNotInIndex(start))
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
325 })?;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
326 idx.remove(start).map_err(revlog_error_from_msg)?;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
327 nt.invalidate_all();
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
328 Self::fill_nodemap(idx, nt)?;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
329 Ok(())
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
330 })
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
331 }
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
332
52787
e5f89bd1a5ee rust-pyo3-revlog: _index___len__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52786
diff changeset
333 fn _index___len__(slf: &Bound<'_, Self>) -> PyResult<usize> {
e5f89bd1a5ee rust-pyo3-revlog: _index___len__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52786
diff changeset
334 Self::with_index_read(slf, |idx| Ok(idx.len()))
e5f89bd1a5ee rust-pyo3-revlog: _index___len__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52786
diff changeset
335 }
52791
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
336
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
337 fn _index___getitem__(
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
338 slf: &Bound<'_, Self>,
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
339 py: Python<'_>,
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
340 key: &Bound<'_, PyAny>,
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
341 ) -> PyResult<PyObject> {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
342 Self::with_index_read(slf, |idx| {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
343 match key.extract::<BaseRevision>() {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
344 Ok(key_as_int) => {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
345 let entry_params = if key_as_int == NULL_REVISION.0 {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
346 RevisionDataParams::default()
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
347 } else {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
348 let rev = UncheckedRevision(key_as_int);
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
349 match idx.entry_as_params(rev) {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
350 Some(e) => e,
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
351 None => {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
352 return Err(PyIndexError::new_err(
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
353 "revlog index out of range",
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
354 ));
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
355 }
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
356 }
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
357 };
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
358 Ok(revision_data_params_to_py_tuple(py, entry_params)?
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
359 .into_any()
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
360 .unbind())
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
361 }
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
362 // Case when key is a binary Node ID (lame: we're re-unlocking)
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
363 _ => Self::_index_get_rev(slf, key.downcast::<PyBytes>()?)?
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
364 .map_or_else(
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
365 || Ok(py.None()),
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
366 |py_rev| Ok(py_rev.into_pyobject(py)?.unbind().into()),
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
367 ),
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
368 }
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
369 })
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
370 }
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
371 }
52778
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52775
diff changeset
372
52782
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
373 impl InnerRevlog {
52784
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
374 /// Take the lock on `slf.irl` for reading and call a closure.
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
375 ///
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
376 /// This serves the purpose to keep the needed intermediate [`PyRef`]
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
377 /// that must be obtained to access the data from the [`Bound`] reference
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
378 /// and of which the locked [`CoreInnerRevlog`] depends.
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
379 /// This also provides releasing of the [`PyRef`] as soon as the closure
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
380 /// is done, which is crucial if the caller needs to obtain a [`PyRefMut`]
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
381 /// later on.
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
382 ///
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
383 /// In the closure, we hand back the intermediate [`PyRef`] that
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
384 /// has been generated so that the closure can access more attributes.
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
385 fn with_core_read<'py, T>(
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
386 slf: &Bound<'py, Self>,
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
387 f: impl FnOnce(
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
388 &PyRef<'py, Self>,
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
389 RwLockReadGuard<CoreInnerRevlog>,
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
390 ) -> PyResult<T>,
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
391 ) -> PyResult<T> {
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
392 let self_ref = slf.borrow();
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
393 // Safety: the owner is the right one. We will anyway
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
394 // not actually `share` it. Perhaps pyo3-sharedref should provide
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
395 // something less scary for this kind of usage.
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
396 let shareable_ref = unsafe { self_ref.irl.borrow_with_owner(slf) };
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
397 let guard = shareable_ref.try_read().map_err(map_try_lock_error)?;
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
398 f(&self_ref, guard)
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
399 }
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
400
52788
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
401 /// Take the lock on `slf.irl` for writing and call a closure.
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
402 ///
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
403 /// See [`Self::with_core_read`] for more explanations.
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
404 fn with_core_write<'py, T>(
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
405 slf: &Bound<'py, Self>,
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
406 f: impl FnOnce(
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
407 &PyRef<'py, Self>,
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
408 RwLockWriteGuard<CoreInnerRevlog>,
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
409 ) -> PyResult<T>,
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
410 ) -> PyResult<T> {
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
411 let self_ref = slf.borrow();
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
412 // Safety: the owner is the right one. We will anyway
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
413 // not actually `share` it. Perhaps pyo3-sharedref should provide
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
414 // something less scary for this kind of usage.
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
415 let shareable_ref = unsafe { self_ref.irl.borrow_with_owner(slf) };
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
416 let guard = shareable_ref.try_write().map_err(map_try_lock_error)?;
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
417 f(&self_ref, guard)
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
418 }
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
419
52784
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
420 fn with_index_read<T>(
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
421 slf: &Bound<'_, Self>,
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
422 f: impl FnOnce(&Index) -> PyResult<T>,
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
423 ) -> PyResult<T> {
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
424 Self::with_core_read(slf, |_, guard| f(&guard.index))
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
425 }
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
426
52788
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
427 #[allow(dead_code)]
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
428 fn with_index_write<T>(
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
429 slf: &Bound<'_, Self>,
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
430 f: impl FnOnce(&mut Index) -> PyResult<T>,
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
431 ) -> PyResult<T> {
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
432 Self::with_core_write(slf, |_, mut guard| f(&mut guard.index))
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
433 }
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
434
52784
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
435 /// Lock `slf` for reading and execute a closure on its [`Index`] and
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
436 /// [`NodeTree`]
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
437 ///
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
438 /// The [`NodeTree`] is initialized an filled before hand if needed.
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
439 fn with_index_nt_read<T>(
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
440 slf: &Bound<'_, Self>,
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
441 f: impl FnOnce(&Index, &CoreNodeTree) -> PyResult<T>,
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
442 ) -> PyResult<T> {
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
443 Self::with_core_read(slf, |self_ref, guard| {
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
444 let idx = &guard.index;
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
445 let nt =
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
446 self_ref.get_nodetree(idx)?.read().map_err(map_lock_error)?;
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
447 let nt = nt.as_ref().expect("nodetree should be set");
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
448 f(idx, nt)
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
449 })
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
450 }
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
451
52788
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
452 fn with_index_nt_write<T>(
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
453 slf: &Bound<'_, Self>,
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
454 f: impl FnOnce(&mut Index, &mut CoreNodeTree) -> PyResult<T>,
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
455 ) -> PyResult<T> {
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
456 Self::with_core_write(slf, |self_ref, mut guard| {
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
457 let idx = &mut guard.index;
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
458 let mut nt = self_ref
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
459 .get_nodetree(idx)?
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
460 .write()
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
461 .map_err(map_lock_error)?;
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
462 let nt = nt.as_mut().expect("nodetree should be set");
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
463 f(idx, nt)
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
464 })
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
465 }
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
466
52782
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
467 /// Fill a [`CoreNodeTree`] by doing a full iteration on the given
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
468 /// [`Index`]
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
469 ///
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
470 /// # Python exceptions
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
471 /// Raises `ValueError` if `nt` has existing data that is inconsistent
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
472 /// with `idx`.
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
473 fn fill_nodemap(idx: &Index, nt: &mut CoreNodeTree) -> PyResult<()> {
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
474 for r in 0..idx.len() {
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
475 let rev = Revision(r as BaseRevision);
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
476 // in this case node() won't ever return None
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
477 nt.insert(idx, idx.node(rev).expect("node should exist"), rev)
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
478 .map_err(nodemap_error)?
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
479 }
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
480 Ok(())
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
481 }
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
482
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
483 /// Return a working NodeTree of this InnerRevlog
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
484 ///
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
485 /// In case the NodeTree has not been initialized yet (in particular
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
486 /// not from persistent data at instantiation), it is created and
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
487 /// filled right away from the index.
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
488 ///
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
489 /// Technically, the returned NodeTree is still behind the lock of
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
490 /// the `nt` field, hence still wrapped in an [`Option`]. Callers
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
491 /// will need to take the lock and unwrap with `expect()`.
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
492 ///
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
493 /// # Python exceptions
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
494 /// The case mentioned in [`Self::fill_nodemap()`] cannot happen, as the
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
495 /// NodeTree is empty when it is called.
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
496 fn get_nodetree(
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
497 &self,
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
498 idx: &Index,
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
499 ) -> PyResult<&RwLock<Option<CoreNodeTree>>> {
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
500 if self.nt.read().map_err(map_lock_error)?.is_none() {
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
501 let readonly = Box::<Vec<_>>::default();
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
502 let mut nt = CoreNodeTree::load_bytes(readonly, 0);
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
503 Self::fill_nodemap(idx, &mut nt)?;
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
504 self.nt.write().map_err(map_lock_error)?.replace(nt);
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
505 }
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
506 Ok(&self.nt)
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
507 }
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
508 }
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
509
52792
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
510 #[pyclass]
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
511 struct NodeTree {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
512 nt: RwLock<CoreNodeTree>,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
513 index: SharedByPyObject<PySharedIndex>,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
514 }
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
515
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
516 #[pymethods]
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
517 impl NodeTree {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
518 #[new]
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
519 // The share/mapping should be set apart to become the PyO3 homolog of
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
520 // `py_rust_index_to_graph`
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
521 fn new(index_proxy: &Bound<'_, PyAny>) -> PyResult<Self> {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
522 let py_irl = index_proxy.getattr("inner")?;
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
523 let py_irl_ref = py_irl.downcast::<InnerRevlog>()?.borrow();
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
524 let shareable_irl = &py_irl_ref.irl;
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
525
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
526 // Safety: the owner is the actual one and we do not leak any
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
527 // internal reference.
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
528 let index = unsafe {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
529 shareable_irl.share_map(&py_irl, |irl| (&irl.index).into())
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
530 };
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
531 let nt = CoreNodeTree::default(); // in-RAM, fully mutable
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
532
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
533 Ok(Self {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
534 nt: nt.into(),
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
535 index,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
536 })
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
537 }
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
538
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
539 /// Tell whether the NodeTree is still valid
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
540 ///
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
541 /// In case of mutation of the index, the given results are not
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
542 /// guaranteed to be correct, and in fact, the methods borrowing
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
543 /// the inner index would fail because of `PySharedRef` poisoning
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
544 /// (generation-based guard), same as iterating on a `dict` that has
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
545 /// been meanwhile mutated.
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
546 fn is_invalidated(&self, py: Python<'_>) -> PyResult<bool> {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
547 // Safety: we don't leak any reference derived from self.index, as
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
548 // we only check errors
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
549 let result = unsafe { self.index.try_borrow(py) };
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
550 // two cases for result to be an error:
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
551 // - the index has previously been mutably borrowed
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
552 // - there is currently a mutable borrow
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
553 // in both cases this amounts for previous results related to
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
554 // the index to still be valid.
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
555 Ok(result.is_err())
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
556 }
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
557
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
558 fn insert(&self, py: Python<'_>, rev: PyRevision) -> PyResult<()> {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
559 // Safety: we don't leak any reference derived from self.index,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
560 // as `nt.insert` does not store direct references
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
561 let idx = &*unsafe { self.index.try_borrow(py)? };
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
562
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
563 let rev = check_revision(idx, rev)?;
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
564 if rev == NULL_REVISION {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
565 return Err(rev_not_in_index(rev.into()));
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
566 }
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
567
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
568 let entry = idx.inner().get_entry(rev).expect("entry should exist");
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
569 let mut nt = self.nt.write().map_err(map_lock_error)?;
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
570 nt.insert(idx, entry.hash(), rev).map_err(nodemap_error)
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
571 }
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
572
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
573 fn shortest(
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
574 &self,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
575 py: Python<'_>,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
576 node: &Bound<'_, PyBytes>,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
577 ) -> PyResult<usize> {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
578 let nt = self.nt.read().map_err(map_lock_error)?;
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
579 // Safety: we don't leak any reference derived from self.index
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
580 // as returned type is Copy
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
581 let idx = &*unsafe { self.index.try_borrow(py)? };
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
582 nt.unique_prefix_len_node(idx, &node_from_py_bytes(node)?)
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
583 .map_err(nodemap_error)?
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
584 .ok_or_else(revlog_error_bare)
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
585 }
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
586
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
587 /// Lookup by node hex prefix in the NodeTree, returning revision number.
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
588 ///
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
589 /// This is not part of the classical NodeTree API, but is good enough
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
590 /// for unit testing, as in `test-rust-revlog.py`.
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
591 fn prefix_rev_lookup(
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
592 &self,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
593 py: Python<'_>,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
594 node_prefix: &Bound<'_, PyBytes>,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
595 ) -> PyResult<Option<PyRevision>> {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
596 let prefix = node_prefix_from_py_bytes(node_prefix)?;
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
597 let nt = self.nt.read().map_err(map_lock_error)?;
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
598 // Safety: we don't leak any reference derived from self.index
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
599 // as returned type is Copy
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
600 let idx = &*unsafe { self.index.try_borrow(py)? };
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
601 Ok(nt
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
602 .find_bin(idx, prefix)
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
603 .map_err(nodemap_error)?
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
604 .map(|r| r.into()))
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
605 }
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
606 }
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
607
52775
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
608 pub fn init_module<'py>(
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
609 py: Python<'py>,
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
610 package: &str,
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
611 ) -> PyResult<Bound<'py, PyModule>> {
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
612 let m = new_submodule(py, package, "revlog")?;
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
613 m.add_class::<InnerRevlog>()?;
52792
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
614 m.add_class::<NodeTree>()?;
52793
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
615 m.add_class::<ReadingContextManager>()?;
52775
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
616 Ok(m)
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
617 }