rust/hg-pyo3/src/revlog/mod.rs
author Georges Racinet <georges.racinet@cloudcrane.io>
Mon, 23 Dec 2024 00:17:03 +0100
changeset 52793 6a70e4931773
parent 52792 acae91fad6be
child 52794 5ad4ed71fbe0
permissions -rw-r--r--
rust-pyo3-revlog: ReadingContextManager Stepping aside from the implementation of index methods to show that this will not be a problem. The test basically only demonstrates that it behaves like a context manager indeed ? of course our fixture does not provide any reasonable file access.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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::{
52792
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
    37
        map_lock_error, map_try_lock_error,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
    38
        nodemap_error, rev_not_in_index, revlog_error_bare,
52784
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
    39
        revlog_error_from_msg,
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
    40
    },
52786
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
    41
    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
    42
    revision::{check_revision, PyRevision},
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    43
    store::PyFnCache,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    44
    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
    45
};
52775
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    46
52778
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52775
diff changeset
    47
mod config;
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    48
use config::*;
52789
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
    49
mod index;
52791
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
    50
use index::{
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
    51
    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
    52
    PySharedIndex,
52791
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
    53
};
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    54
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    55
#[pyclass]
52793
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    56
struct ReadingContextManager {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    57
    inner_revlog: Py<InnerRevlog>,
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
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    60
#[pymethods]
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    61
impl ReadingContextManager {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    62
    fn __enter__(slf: PyRef<'_, Self>) -> PyResult<()> {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    63
        let inner_bound = slf.inner_revlog.bind(slf.py());
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    64
        let shareable = &inner_bound.borrow().irl;
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    65
        // 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
    66
        let core_irl =
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    67
            unsafe { shareable.borrow_with_owner(inner_bound) }.read();
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    68
        core_irl
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    69
            .enter_reading_context()
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    70
            .map_err(revlog_error_from_msg)
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    71
            .inspect_err(|_e| {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    72
                // `__exit__` is not called from Python if `__enter__` fails
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    73
                core_irl.exit_reading_context();
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
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    77
    #[pyo3(signature = (*_args))]
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    78
    fn __exit__(slf: PyRef<'_, Self>, _args: &Bound<'_, PyTuple>) {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    79
        let inner_bound = slf.inner_revlog.bind(slf.py());
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    80
        let shareable = &inner_bound.borrow().irl;
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    81
        // 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
    82
        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
    83
        core_irl_ref.read().exit_reading_context();
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
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
    87
#[pyclass]
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    88
#[allow(dead_code)]
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    89
struct InnerRevlog {
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    90
    irl: PyShareable<CoreInnerRevlog>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    91
    nt: RwLock<Option<CoreNodeTree>>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    92
    docket: Option<PyObject>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    93
    // 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
    94
    nodemap_mmap: Option<PyBuffer<u8>>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    95
    // 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
    96
    index_mmap: Option<PyBuffer<u8>>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    97
    revision_cache: Option<PyObject>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
    98
    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
    99
    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
   100
    use_persistent_nodemap: bool,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   101
    nodemap_queries: AtomicUsize,
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
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   104
#[pymethods]
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   105
impl InnerRevlog {
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   106
    #[new]
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   107
    // 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
   108
    #[allow(clippy::too_many_arguments)]
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   109
    fn new(
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   110
        vfs_base: &Bound<'_, PyBytes>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   111
        fncache: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   112
        vfs_is_readonly: bool,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   113
        index_data: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   114
        index_file: &Bound<'_, PyBytes>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   115
        data_file: &Bound<'_, PyBytes>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   116
        sidedata_file: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   117
        inline: bool,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   118
        data_config: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   119
        delta_config: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   120
        feature_config: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   121
        chunk_cache: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   122
        default_compression_header: &Bound<'_, PyAny>,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   123
        revlog_type: usize,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   124
        use_persistent_nodemap: bool,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   125
    ) -> PyResult<Self> {
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   126
        // 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
   127
        // a blank `allow` directive
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   128
        let _ = sidedata_file;
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   129
        let _ = chunk_cache;
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   130
        let _ = default_compression_header;
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   131
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   132
        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
   133
        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
   134
        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
   135
            .map_err(revlog_error_from_msg)?;
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   136
        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
   137
        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
   138
        let feature_config =
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   139
            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
   140
        let options = RevlogOpenOptions::new(
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   141
            inline,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   142
            data_config,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   143
            delta_config,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   144
            feature_config,
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
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   147
        // 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
   148
        // `index_mmap`
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   149
        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
   150
        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
   151
            .map_err(revlog_error_from_msg)?;
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   152
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   153
        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
   154
        let core = CoreInnerRevlog::new(
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   155
            Box::new(FnCacheVfs::new(
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   156
                base,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   157
                vfs_is_readonly,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   158
                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
   159
            )),
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   160
            index,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   161
            index_file,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   162
            data_file,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   163
            data_config,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   164
            delta_config,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   165
            feature_config,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   166
        );
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   167
        Ok(Self {
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   168
            irl: core.into(),
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   169
            nt: None.into(),
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   170
            docket: None,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   171
            nodemap_mmap: None,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   172
            index_mmap: buf.into(),
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   173
            head_revs_py_list: None,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   174
            head_node_ids_py_list: None,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   175
            revision_cache: None,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   176
            use_persistent_nodemap,
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   177
            nodemap_queries: AtomicUsize::new(0),
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   178
        })
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   179
    }
52786
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   180
52793
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
   181
    fn reading(slf: &Bound<'_, Self>) -> PyResult<ReadingContextManager> {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
   182
        Ok(ReadingContextManager {
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
   183
            inner_revlog: slf.clone().unbind(),
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
    }
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
   186
52786
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   187
    //
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   188
    // -- forwarded index methods --
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
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   191
    fn _index_get_rev(
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   192
        slf: &Bound<'_, Self>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   193
        node: &Bound<'_, PyBytes>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   194
    ) -> PyResult<Option<PyRevision>> {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   195
        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
   196
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   197
        // 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
   198
        // 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
   199
        // 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
   200
        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
   201
            let idx = &irl.index;
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
            let prev_queries =
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   204
                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
   205
            // 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
   206
            // 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
   207
            // 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
   208
            // (automation file that changes every
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   209
            // 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
   210
            // all measured purposes so far.
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   211
            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
   212
                return Ok(idx
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   213
                    .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
   214
                    .ok()
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   215
                    .map(Into::into));
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
            let opt =
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   219
                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
   220
            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
   221
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   222
            let rust_rev =
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   223
                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
   224
            Ok(rust_rev.map(Into::into))
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
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   228
    /// 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
   229
    /// node is not found.
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   230
    ///
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   231
    /// 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
   232
    /// will catch and rewrap with it
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   233
    fn _index_rev(
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   234
        slf: &Bound<'_, Self>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   235
        node: &Bound<'_, PyBytes>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   236
    ) -> PyResult<PyRevision> {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   237
        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
   238
    }
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   239
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   240
    /// 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
   241
    fn _index_has_node(
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   242
        slf: &Bound<'_, Self>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   243
        node: &Bound<'_, PyBytes>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   244
    ) -> PyResult<bool> {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   245
        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
   246
    }
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   247
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   248
    /// 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
   249
    fn _index_shortest(
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   250
        slf: &Bound<'_, Self>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   251
        node: &Bound<'_, PyBytes>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   252
    ) -> PyResult<usize> {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   253
        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
   254
            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
   255
                Ok(Some(l)) => Ok(l),
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   256
                Ok(None) => Err(revlog_error_bare()),
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   257
                Err(e) => Err(nodemap_error(e)),
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
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   262
    fn _index_partialmatch<'py>(
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   263
        slf: &Bound<'py, Self>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   264
        node: &Bound<'py, PyBytes>,
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   265
    ) -> PyResult<Option<Bound<'py, PyBytes>>> {
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   266
        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
   267
            Ok(nt
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   268
                .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
   269
                .map_err(nodemap_error)?
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   270
                .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
   271
        })
4e34e8fd46d4 rust-pyo3-revlog: nodemap based index methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52784
diff changeset
   272
    }
52787
e5f89bd1a5ee rust-pyo3-revlog: _index___len__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52786
diff changeset
   273
52789
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   274
    /// append an index entry
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   275
    fn _index_append(
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   276
        slf: &Bound<'_, Self>,
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   277
        tup: &Bound<'_, PyTuple>,
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   278
    ) -> PyResult<()> {
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   279
        // 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
   280
        // proper errors
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   281
        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
   282
        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
   283
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   284
        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
   285
            let rev = idx.len() as BaseRevision;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   286
            // 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
   287
            // index
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   288
            let rev = Revision(rev);
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   289
            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
   290
                .map_err(revlog_error_from_msg)?;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   291
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   292
            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
   293
            Ok(())
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
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   297
    /// 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
   298
    ///
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   299
    /// 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
   300
    /// 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
   301
    /// 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
   302
    fn _index___delitem__(
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   303
        slf: &Bound<'_, Self>,
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   304
        arg: &Bound<'_, PyAny>,
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   305
    ) -> PyResult<()> {
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   306
        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
   307
            UncheckedRevision(rev)
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   308
        } else {
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   309
            // 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
   310
            // 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
   311
            // `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
   312
            // 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
   313
            // 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
   314
            // with the C index).
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   315
            let start = arg.getattr("start")?;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   316
            UncheckedRevision(start.extract()?)
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
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   319
        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
   320
            // 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
   321
            // `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
   322
            // `PySlice_GetIndicesEx`
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   323
            // (Python integration tests will tell us)
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   324
            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
   325
                nodemap_error(NodeMapError::RevisionNotInIndex(start))
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   326
            })?;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   327
            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
   328
            nt.invalidate_all();
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   329
            Self::fill_nodemap(idx, nt)?;
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   330
            Ok(())
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
    }
34f44aa5e844 rust-pyo3-index: first mutating methods
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52788
diff changeset
   333
52787
e5f89bd1a5ee rust-pyo3-revlog: _index___len__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52786
diff changeset
   334
    fn _index___len__(slf: &Bound<'_, Self>) -> PyResult<usize> {
e5f89bd1a5ee rust-pyo3-revlog: _index___len__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52786
diff changeset
   335
        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
   336
    }
52791
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   337
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   338
    fn _index___getitem__(
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   339
        slf: &Bound<'_, Self>,
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   340
        py: Python<'_>,
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   341
        key: &Bound<'_, PyAny>,
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   342
    ) -> PyResult<PyObject> {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   343
        Self::with_index_read(slf, |idx| {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   344
            match key.extract::<BaseRevision>() {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   345
                Ok(key_as_int) => {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   346
                    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
   347
                        RevisionDataParams::default()
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   348
                    } else {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   349
                        let rev = UncheckedRevision(key_as_int);
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   350
                        match idx.entry_as_params(rev) {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   351
                            Some(e) => e,
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   352
                            None => {
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   353
                                return Err(PyIndexError::new_err(
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   354
                                    "revlog index out of range",
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
                    };
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   359
                    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
   360
                        .into_any()
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   361
                        .unbind())
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   362
                }
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   363
                // 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
   364
                _ => Self::_index_get_rev(slf, key.downcast::<PyBytes>()?)?
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   365
                    .map_or_else(
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   366
                        || Ok(py.None()),
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   367
                        |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
   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
        })
0ac956db7ea7 rust-pyo3-index: __getitem__
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52789
diff changeset
   371
    }
52780
42b219a1404a rust-pyo3-revlog: InnerRevlog definition and constructor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52778
diff changeset
   372
}
52778
523ca3d225f5 rust-pyo3-revlog: config extraction functions
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52775
diff changeset
   373
52782
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   374
impl InnerRevlog {
52784
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   375
    /// 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
   376
    ///
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   377
    /// 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
   378
    /// 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
   379
    /// 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
   380
    /// 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
   381
    /// 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
   382
    /// later on.
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   383
    ///
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   384
    /// 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
   385
    /// 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
   386
    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
   387
        slf: &Bound<'py, Self>,
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   388
        f: impl FnOnce(
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   389
            &PyRef<'py, Self>,
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   390
            RwLockReadGuard<CoreInnerRevlog>,
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
    ) -> PyResult<T> {
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   393
        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
   394
        // 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
   395
        // 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
   396
        // 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
   397
        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
   398
        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
   399
        f(&self_ref, guard)
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   400
    }
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   401
52788
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   402
    /// 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
   403
    ///
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   404
    /// 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
   405
    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
   406
        slf: &Bound<'py, Self>,
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   407
        f: impl FnOnce(
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   408
            &PyRef<'py, Self>,
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   409
            RwLockWriteGuard<CoreInnerRevlog>,
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
    ) -> PyResult<T> {
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   412
        let self_ref = slf.borrow();
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   413
        // 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
   414
        // 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
   415
        // 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
   416
        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
   417
        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
   418
        f(&self_ref, guard)
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   419
    }
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   420
52784
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   421
    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
   422
        slf: &Bound<'_, Self>,
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   423
        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
   424
    ) -> PyResult<T> {
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   425
        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
   426
    }
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   427
52788
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   428
    #[allow(dead_code)]
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   429
    fn with_index_write<T>(
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   430
        slf: &Bound<'_, Self>,
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   431
        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
   432
    ) -> PyResult<T> {
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   433
        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
   434
    }
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   435
52784
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   436
    /// 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
   437
    /// [`NodeTree`]
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   438
    ///
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   439
    /// 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
   440
    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
   441
        slf: &Bound<'_, Self>,
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   442
        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
   443
    ) -> PyResult<T> {
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   444
        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
   445
            let idx = &guard.index;
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   446
            let nt =
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   447
                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
   448
            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
   449
            f(idx, nt)
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
    }
5e3e8876fd9e rust-pyo3-revlog: index and nodetree read accessor helpers
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52782
diff changeset
   452
52788
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   453
    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
   454
        slf: &Bound<'_, Self>,
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   455
        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
   456
    ) -> PyResult<T> {
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   457
        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
   458
            let idx = &mut guard.index;
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   459
            let mut nt = self_ref
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   460
                .get_nodetree(idx)?
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   461
                .write()
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   462
                .map_err(map_lock_error)?;
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   463
            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
   464
            f(idx, nt)
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
    }
e29e75e8328c rust-pyo3-revlog: index and notetree writing accessors
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52787
diff changeset
   467
52782
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   468
    /// 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
   469
    /// [`Index`]
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   470
    ///
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   471
    /// # Python exceptions
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   472
    /// 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
   473
    /// with `idx`.
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   474
    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
   475
        for r in 0..idx.len() {
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   476
            let rev = Revision(r as BaseRevision);
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   477
            // 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
   478
            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
   479
                .map_err(nodemap_error)?
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   480
        }
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   481
        Ok(())
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
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   484
    /// Return a working NodeTree of this InnerRevlog
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   485
    ///
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   486
    /// 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
   487
    /// 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
   488
    /// filled right away from the index.
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   489
    ///
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   490
    /// 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
   491
    /// 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
   492
    /// 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
   493
    ///
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   494
    /// # Python exceptions
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   495
    /// 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
   496
    /// NodeTree is empty when it is called.
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   497
    fn get_nodetree(
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   498
        &self,
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   499
        idx: &Index,
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   500
    ) -> PyResult<&RwLock<Option<CoreNodeTree>>> {
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   501
        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
   502
            let readonly = Box::<Vec<_>>::default();
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   503
            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
   504
            Self::fill_nodemap(idx, &mut nt)?;
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   505
            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
   506
        }
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   507
        Ok(&self.nt)
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
}
827889802d11 rust-pyo3-revlog: nodemap filling accessor
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52780
diff changeset
   510
52792
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   511
#[pyclass]
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   512
struct NodeTree {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   513
    nt: RwLock<CoreNodeTree>,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   514
    index: SharedByPyObject<PySharedIndex>,
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
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   517
#[pymethods]
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   518
impl NodeTree {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   519
    #[new]
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   520
    // 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
   521
    // `py_rust_index_to_graph`
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   522
    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
   523
        let py_irl = index_proxy.getattr("inner")?;
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   524
        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
   525
        let shareable_irl = &py_irl_ref.irl;
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   526
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   527
        // 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
   528
        // internal reference.
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   529
        let index = unsafe {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   530
            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
   531
        };
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   532
        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
   533
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   534
        Ok(Self {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   535
            nt: nt.into(),
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   536
            index,
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
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   540
    /// Tell whether the NodeTree is still valid
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   541
    ///
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   542
    /// 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
   543
    /// 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
   544
    /// 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
   545
    /// (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
   546
    /// been meanwhile mutated.
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   547
    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
   548
        // 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
   549
        // we only check errors
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   550
        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
   551
        // 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
   552
        // - the index has previously been mutably borrowed
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   553
        // - there is currently a mutable borrow
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   554
        // 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
   555
        // the index to still be valid.
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   556
        Ok(result.is_err())
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
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   559
    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
   560
        // 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
   561
        // 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
   562
        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
   563
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   564
        let rev = check_revision(idx, rev)?;
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   565
        if rev == NULL_REVISION {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   566
            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
   567
        }
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   568
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   569
        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
   570
        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
   571
        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
   572
    }
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   573
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   574
    fn shortest(
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   575
        &self,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   576
        py: Python<'_>,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   577
        node: &Bound<'_, PyBytes>,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   578
    ) -> PyResult<usize> {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   579
        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
   580
        // 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
   581
        // as returned type is Copy
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   582
        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
   583
        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
   584
            .map_err(nodemap_error)?
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   585
            .ok_or_else(revlog_error_bare)
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
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   588
    /// 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
   589
    ///
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   590
    /// 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
   591
    /// 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
   592
    fn prefix_rev_lookup(
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   593
        &self,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   594
        py: Python<'_>,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   595
        node_prefix: &Bound<'_, PyBytes>,
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   596
    ) -> PyResult<Option<PyRevision>> {
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   597
        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
   598
        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
   599
        // 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
   600
        // as returned type is Copy
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   601
        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
   602
        Ok(nt
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   603
            .find_bin(idx, prefix)
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   604
            .map_err(nodemap_error)?
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   605
            .map(|r| r.into()))
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
}
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   608
52775
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   609
pub fn init_module<'py>(
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   610
    py: Python<'py>,
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   611
    package: &str,
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   612
) -> PyResult<Bound<'py, PyModule>> {
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   613
    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
   614
    m.add_class::<InnerRevlog>()?;
52792
acae91fad6be rust-pyo3-revlog: standalone NodeTree class
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52791
diff changeset
   615
    m.add_class::<NodeTree>()?;
52793
6a70e4931773 rust-pyo3-revlog: ReadingContextManager
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52792
diff changeset
   616
    m.add_class::<ReadingContextManager>()?;
52775
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   617
    Ok(m)
264047bf4b9b rust-pyo3-revlog: new Python and Rust module
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
   618
}