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