Mercurial > public > mercurial-scm > hg
annotate rust/hg-pyo3/src/revlog/mod.rs @ 52789:34f44aa5e844
rust-pyo3-index: first mutating methods
This brings in `append()` and `__delitem__`, and is for us the
first validation of our inner mutability.
In the case of `__delitem__`, there was a tricky case where we
were tempted to use the higher level `PySlice::indices` API, with
a possible dangerous change of behaviour. We test it carefully from
the Python side.
author | Georges Racinet <georges.racinet@cloudcrane.io> |
---|---|
date | Wed, 25 Dec 2024 17:17:47 +0100 |
parents | e29e75e8328c |
children | 0ac956db7ea7 |
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; |
52775
264047bf4b9b
rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
11 use pyo3::prelude::*; |
52789
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
12 use pyo3::types::{PyBytes, PyBytesMethods, PyList, PyTuple}; |
52780
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
13 use pyo3_sharedref::PyShareable; |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
14 |
52786
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
15 use std::sync::{ |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
16 atomic::{AtomicUsize, Ordering}, |
52788
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
17 RwLock, RwLockReadGuard, RwLockWriteGuard, |
52786
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
18 }; |
52775
264047bf4b9b
rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
19 |
52780
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
20 use hg::{ |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
21 revlog::{ |
52786
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
22 index::Index, |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
23 inner_revlog::InnerRevlog as CoreInnerRevlog, |
52789
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
24 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
|
25 options::RevlogOpenOptions, |
52782
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
26 RevlogIndex, RevlogType, |
52780
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
27 }, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
28 utils::files::get_path_from_bytes, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
29 vfs::FnCacheVfs, |
52789
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
30 BaseRevision, Revision, UncheckedRevision, |
52780
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
31 }; |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
32 |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
33 use crate::{ |
52784
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
34 exceptions::{ |
52786
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
35 map_lock_error, map_try_lock_error, nodemap_error, revlog_error_bare, |
52784
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
36 revlog_error_from_msg, |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
37 }, |
52786
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
38 node::{node_from_py_bytes, node_prefix_from_py_bytes, py_node_for_rev}, |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
39 revision::PyRevision, |
52780
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
40 store::PyFnCache, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
41 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
|
42 }; |
52775
264047bf4b9b
rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
43 |
52778
523ca3d225f5
rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52775
diff
changeset
|
44 mod config; |
52780
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
45 use config::*; |
52789
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
46 mod index; |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
47 use index::py_tuple_to_revision_data_params; |
52780
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
48 |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
49 #[pyclass] |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
50 #[allow(dead_code)] |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
51 struct InnerRevlog { |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
52 irl: PyShareable<CoreInnerRevlog>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
53 nt: RwLock<Option<CoreNodeTree>>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
54 docket: Option<PyObject>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
55 // 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
|
56 nodemap_mmap: Option<PyBuffer<u8>>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
57 // 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
|
58 index_mmap: Option<PyBuffer<u8>>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
59 revision_cache: Option<PyObject>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
60 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
|
61 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
|
62 use_persistent_nodemap: bool, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
63 nodemap_queries: AtomicUsize, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
64 } |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
65 |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
66 #[pymethods] |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
67 impl InnerRevlog { |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
68 #[new] |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
69 // 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
|
70 #[allow(clippy::too_many_arguments)] |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
71 fn new( |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
72 vfs_base: &Bound<'_, PyBytes>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
73 fncache: &Bound<'_, PyAny>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
74 vfs_is_readonly: bool, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
75 index_data: &Bound<'_, PyAny>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
76 index_file: &Bound<'_, PyBytes>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
77 data_file: &Bound<'_, PyBytes>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
78 sidedata_file: &Bound<'_, PyAny>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
79 inline: bool, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
80 data_config: &Bound<'_, PyAny>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
81 delta_config: &Bound<'_, PyAny>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
82 feature_config: &Bound<'_, PyAny>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
83 chunk_cache: &Bound<'_, PyAny>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
84 default_compression_header: &Bound<'_, PyAny>, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
85 revlog_type: usize, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
86 use_persistent_nodemap: bool, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
87 ) -> PyResult<Self> { |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
88 // 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
|
89 // a blank `allow` directive |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
90 let _ = sidedata_file; |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
91 let _ = chunk_cache; |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
92 let _ = default_compression_header; |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
93 |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
94 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
|
95 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
|
96 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
|
97 .map_err(revlog_error_from_msg)?; |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
98 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
|
99 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
|
100 let feature_config = |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
101 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
|
102 let options = RevlogOpenOptions::new( |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
103 inline, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
104 data_config, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
105 delta_config, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
106 feature_config, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
107 ); |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
108 |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
109 // 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
|
110 // `index_mmap` |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
111 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
|
112 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
|
113 .map_err(revlog_error_from_msg)?; |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
114 |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
115 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
|
116 let core = CoreInnerRevlog::new( |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
117 Box::new(FnCacheVfs::new( |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
118 base, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
119 vfs_is_readonly, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
120 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
|
121 )), |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
122 index, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
123 index_file, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
124 data_file, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
125 data_config, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
126 delta_config, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
127 feature_config, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
128 ); |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
129 Ok(Self { |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
130 irl: core.into(), |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
131 nt: None.into(), |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
132 docket: None, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
133 nodemap_mmap: None, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
134 index_mmap: buf.into(), |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
135 head_revs_py_list: None, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
136 head_node_ids_py_list: None, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
137 revision_cache: None, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
138 use_persistent_nodemap, |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
139 nodemap_queries: AtomicUsize::new(0), |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
140 }) |
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
141 } |
52786
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
142 |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
143 // |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
144 // -- forwarded index methods -- |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
145 // |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
146 |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
147 fn _index_get_rev( |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
148 slf: &Bound<'_, Self>, |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
149 node: &Bound<'_, PyBytes>, |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
150 ) -> PyResult<Option<PyRevision>> { |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
151 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
|
152 |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
153 // 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
|
154 // 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
|
155 // 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
|
156 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
|
157 let idx = &irl.index; |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
158 |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
159 let prev_queries = |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
160 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
|
161 // 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
|
162 // 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
|
163 // 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
|
164 // (automation file that changes every |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
165 // 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
|
166 // all measured purposes so far. |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
167 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
|
168 return Ok(idx |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
169 .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
|
170 .ok() |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
171 .map(Into::into)); |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
172 } |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
173 |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
174 let opt = |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
175 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
|
176 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
|
177 |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
178 let rust_rev = |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
179 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
|
180 Ok(rust_rev.map(Into::into)) |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
181 }) |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
182 } |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
183 |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
184 /// 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
|
185 /// node is not found. |
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 /// 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
|
188 /// will catch and rewrap with it |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
189 fn _index_rev( |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
190 slf: &Bound<'_, Self>, |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
191 node: &Bound<'_, PyBytes>, |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
192 ) -> PyResult<PyRevision> { |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
193 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
|
194 } |
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 /// 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
|
197 fn _index_has_node( |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
198 slf: &Bound<'_, Self>, |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
199 node: &Bound<'_, PyBytes>, |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
200 ) -> PyResult<bool> { |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
201 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
|
202 } |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
203 |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
204 /// 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
|
205 fn _index_shortest( |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
206 slf: &Bound<'_, Self>, |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
207 node: &Bound<'_, PyBytes>, |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
208 ) -> PyResult<usize> { |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
209 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
|
210 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
|
211 Ok(Some(l)) => Ok(l), |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
212 Ok(None) => Err(revlog_error_bare()), |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
213 Err(e) => Err(nodemap_error(e)), |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
214 } |
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 |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
218 fn _index_partialmatch<'py>( |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
219 slf: &Bound<'py, Self>, |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
220 node: &Bound<'py, PyBytes>, |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
221 ) -> PyResult<Option<Bound<'py, PyBytes>>> { |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
222 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
|
223 Ok(nt |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
224 .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
|
225 .map_err(nodemap_error)? |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
226 .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
|
227 }) |
4e34e8fd46d4
rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52784
diff
changeset
|
228 } |
52787
e5f89bd1a5ee
rust-pyo3-revlog: _index___len__
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52786
diff
changeset
|
229 |
52789
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
230 /// append an index entry |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
231 fn _index_append( |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
232 slf: &Bound<'_, Self>, |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
233 tup: &Bound<'_, PyTuple>, |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
234 ) -> PyResult<()> { |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
235 // 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
|
236 // proper errors |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
237 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
|
238 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
|
239 |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
240 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
|
241 let rev = idx.len() as BaseRevision; |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
242 // 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
|
243 // index |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
244 let rev = Revision(rev); |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
245 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
|
246 .map_err(revlog_error_from_msg)?; |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
247 |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
248 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
|
249 Ok(()) |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
250 }) |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
251 } |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
252 |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
253 /// 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
|
254 /// |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
255 /// 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
|
256 /// 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
|
257 /// 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
|
258 fn _index___delitem__( |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
259 slf: &Bound<'_, Self>, |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
260 arg: &Bound<'_, PyAny>, |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
261 ) -> PyResult<()> { |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
262 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
|
263 UncheckedRevision(rev) |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
264 } else { |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
265 // 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
|
266 // 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
|
267 // `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
|
268 // 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
|
269 // 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
|
270 // with the C index). |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
271 let start = arg.getattr("start")?; |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
272 UncheckedRevision(start.extract()?) |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
273 }; |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
274 |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
275 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
|
276 // 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
|
277 // `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
|
278 // `PySlice_GetIndicesEx` |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
279 // (Python integration tests will tell us) |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
280 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
|
281 nodemap_error(NodeMapError::RevisionNotInIndex(start)) |
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 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
|
284 nt.invalidate_all(); |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
285 Self::fill_nodemap(idx, nt)?; |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
286 Ok(()) |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
287 }) |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
288 } |
34f44aa5e844
rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52788
diff
changeset
|
289 |
52787
e5f89bd1a5ee
rust-pyo3-revlog: _index___len__
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52786
diff
changeset
|
290 fn _index___len__(slf: &Bound<'_, Self>) -> PyResult<usize> { |
e5f89bd1a5ee
rust-pyo3-revlog: _index___len__
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52786
diff
changeset
|
291 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
|
292 } |
52780
42b219a1404a
rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52778
diff
changeset
|
293 } |
52778
523ca3d225f5
rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52775
diff
changeset
|
294 |
52782
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
295 impl InnerRevlog { |
52784
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
296 /// 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
|
297 /// |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
298 /// 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
|
299 /// 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
|
300 /// 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
|
301 /// 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
|
302 /// 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
|
303 /// later on. |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
304 /// |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
305 /// 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
|
306 /// 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
|
307 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
|
308 slf: &Bound<'py, Self>, |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
309 f: impl FnOnce( |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
310 &PyRef<'py, Self>, |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
311 RwLockReadGuard<CoreInnerRevlog>, |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
312 ) -> PyResult<T>, |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
313 ) -> PyResult<T> { |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
314 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
|
315 // 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
|
316 // 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
|
317 // 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
|
318 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
|
319 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
|
320 f(&self_ref, guard) |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
321 } |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
322 |
52788
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
323 /// 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
|
324 /// |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
325 /// 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
|
326 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
|
327 slf: &Bound<'py, Self>, |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
328 f: impl FnOnce( |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
329 &PyRef<'py, Self>, |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
330 RwLockWriteGuard<CoreInnerRevlog>, |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
331 ) -> PyResult<T>, |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
332 ) -> PyResult<T> { |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
333 let self_ref = slf.borrow(); |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
334 // 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
|
335 // 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
|
336 // 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
|
337 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
|
338 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
|
339 f(&self_ref, guard) |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
340 } |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
341 |
52784
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
342 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
|
343 slf: &Bound<'_, Self>, |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
344 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
|
345 ) -> PyResult<T> { |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
346 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
|
347 } |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
348 |
52788
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
349 #[allow(dead_code)] |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
350 fn with_index_write<T>( |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
351 slf: &Bound<'_, Self>, |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
352 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
|
353 ) -> PyResult<T> { |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
354 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
|
355 } |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
356 |
52784
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
357 /// 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
|
358 /// [`NodeTree`] |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
359 /// |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
360 /// 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
|
361 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
|
362 slf: &Bound<'_, Self>, |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
363 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
|
364 ) -> PyResult<T> { |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
365 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
|
366 let idx = &guard.index; |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
367 let nt = |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
368 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
|
369 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
|
370 f(idx, nt) |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
371 }) |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
372 } |
5e3e8876fd9e
rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52782
diff
changeset
|
373 |
52788
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
374 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
|
375 slf: &Bound<'_, Self>, |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
376 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
|
377 ) -> PyResult<T> { |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
378 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
|
379 let idx = &mut guard.index; |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
380 let mut nt = self_ref |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
381 .get_nodetree(idx)? |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
382 .write() |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
383 .map_err(map_lock_error)?; |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
384 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
|
385 f(idx, nt) |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
386 }) |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
387 } |
e29e75e8328c
rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52787
diff
changeset
|
388 |
52782
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
389 /// 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
|
390 /// [`Index`] |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
391 /// |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
392 /// # Python exceptions |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
393 /// 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
|
394 /// with `idx`. |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
395 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
|
396 for r in 0..idx.len() { |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
397 let rev = Revision(r as BaseRevision); |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
398 // 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
|
399 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
|
400 .map_err(nodemap_error)? |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
401 } |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
402 Ok(()) |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
403 } |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
404 |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
405 /// Return a working NodeTree of this InnerRevlog |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
406 /// |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
407 /// 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
|
408 /// 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
|
409 /// filled right away from the index. |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
410 /// |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
411 /// 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
|
412 /// 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
|
413 /// 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
|
414 /// |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
415 /// # Python exceptions |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
416 /// 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
|
417 /// NodeTree is empty when it is called. |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
418 fn get_nodetree( |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
419 &self, |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
420 idx: &Index, |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
421 ) -> PyResult<&RwLock<Option<CoreNodeTree>>> { |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
422 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
|
423 let readonly = Box::<Vec<_>>::default(); |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
424 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
|
425 Self::fill_nodemap(idx, &mut nt)?; |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
426 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
|
427 } |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
428 Ok(&self.nt) |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
429 } |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
430 } |
827889802d11
rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52780
diff
changeset
|
431 |
52775
264047bf4b9b
rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
432 pub fn init_module<'py>( |
264047bf4b9b
rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
433 py: Python<'py>, |
264047bf4b9b
rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
434 package: &str, |
264047bf4b9b
rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
435 ) -> PyResult<Bound<'py, PyModule>> { |
264047bf4b9b
rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
436 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
|
437 m.add_class::<InnerRevlog>()?; |
52775
264047bf4b9b
rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
438 Ok(m) |
264047bf4b9b
rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
439 } |