rust/hg-cpython/src/revlog.rs
author Raphaël Gomès <rgomes@octobus.net>
Wed, 02 Aug 2023 16:49:17 +0200
changeset 51208 274abd1562a2
parent 51207 b67cd0d0e976
child 51210 72d16685d63a
permissions -rw-r--r--
rust-index: use the rust index in `shortest`
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::{
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
     9
    cindex,
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},
51201
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
    16
    ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyInt, PyModule,
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
    17
    PyObject, PyResult, PyString, PyTuple, Python, PythonObject, ToPyObject,
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    18
};
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
    19
use hg::{
51205
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
    20
    index::{IndexHeader, RevisionDataParams},
44509
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
    21
    nodemap::{Block, NodeMapError, NodeTree},
46432
18a261b11b20 rust: Remove hex parsing from the nodemap
Simon Sapin <simon.sapin@octobus.net>
parents: 46431
diff changeset
    22
    revlog::{nodemap::NodeMap, NodePrefix, RevlogIndex},
51205
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
    23
    BaseRevision, 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
    24
};
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    25
use std::cell::RefCell;
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
    26
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    27
/// Return a Struct implementing the Graph trait
44070
451d22174b5f revlog: run rustfmt nightly
Augie Fackler <augie@google.com>
parents: 44012
diff changeset
    28
pub(crate) fn pyindex_to_graph(
451d22174b5f revlog: run rustfmt nightly
Augie Fackler <augie@google.com>
parents: 44012
diff changeset
    29
    py: Python,
451d22174b5f revlog: run rustfmt nightly
Augie Fackler <augie@google.com>
parents: 44012
diff changeset
    30
    index: PyObject,
451d22174b5f revlog: run rustfmt nightly
Augie Fackler <augie@google.com>
parents: 44012
diff changeset
    31
) -> PyResult<cindex::Index> {
44011
c627f1b2f3c3 rust-index: handle `MixedIndex` in `pyindex_to_graph`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44010
diff changeset
    32
    match index.extract::<MixedIndex>(py) {
c627f1b2f3c3 rust-index: handle `MixedIndex` in `pyindex_to_graph`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44010
diff changeset
    33
        Ok(midx) => Ok(midx.clone_cindex(py)),
c627f1b2f3c3 rust-index: handle `MixedIndex` in `pyindex_to_graph`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44010
diff changeset
    34
        Err(_) => cindex::Index::new(py, index),
c627f1b2f3c3 rust-index: handle `MixedIndex` in `pyindex_to_graph`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44010
diff changeset
    35
    }
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
    36
}
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    37
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    38
py_class!(pub class MixedIndex |py| {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    39
    data cindex: RefCell<cindex::Index>;
51190
6ec8387eb0be rust-index: pass data down to the Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51187
diff changeset
    40
    data index: RefCell<hg::index::Index>;
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
    41
    data nt: RefCell<Option<NodeTree>>;
44509
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
    42
    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
    43
    // 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
    44
    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
    45
    // 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
    46
    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
    47
51190
6ec8387eb0be rust-index: pass data down to the Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51187
diff changeset
    48
    def __new__(
6ec8387eb0be rust-index: pass data down to the Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51187
diff changeset
    49
        _cls,
6ec8387eb0be rust-index: pass data down to the Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51187
diff changeset
    50
        cindex: PyObject,
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
    51
        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
    52
        default_header: u32,
51190
6ec8387eb0be rust-index: pass data down to the Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51187
diff changeset
    53
    ) -> PyResult<MixedIndex> {
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
    54
        Self::new(py, cindex, data, default_header)
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    55
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    56
44012
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    57
    /// 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
    58
    ///
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    59
    /// 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
    60
    /// 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
    61
    /// 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
    62
    /// this, by exposing our own standalone nodemap class,
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    63
    /// ready to accept `MixedIndex`.
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    64
    def get_cindex(&self) -> PyResult<PyObject> {
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    65
        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
    66
    }
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    67
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
    68
    // 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
    69
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
    70
    /// 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
    71
    /// 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
    72
    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
    73
        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
    74
        let nt = opt.as_ref().unwrap();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    75
        let idx = &*self.cindex(py).borrow();
51196
f95f70cf2ee2 rust-index: check rindex and cindex return the same get_rev
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
    76
        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
    77
        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
    78
        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
    79
            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
    80
        let c_rev =
f95f70cf2ee2 rust-index: check rindex and cindex return the same get_rev
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
    81
            nt.find_bin(idx, 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
    82
        assert_eq!(rust_rev, c_rev);
f95f70cf2ee2 rust-index: check rindex and cindex return the same get_rev
Raphaël Gomès <rgomes@octobus.net>
parents: 51195
diff changeset
    83
        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
    84
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
    85
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    86
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    87
    /// 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
    88
    /// 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
    89
    ///
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    90
    /// 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
    91
    /// will catch and rewrap with it
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
    92
    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
    93
        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
    94
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    95
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    96
    /// 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
    97
    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
    98
        // 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
    99
        // 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
   100
        // 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
   101
        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
   102
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   103
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   104
    /// 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
   105
    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
   106
        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
   107
        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
   108
        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
   109
        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
   110
        {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   111
            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
   112
            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
   113
            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
   114
        }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   115
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   116
48269
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
   117
    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
   118
        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
   119
        let nt = opt.as_ref().unwrap();
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
        let idx = &*self.cindex(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
   121
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 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
   123
            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
   124
        }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   125
        else {
48269
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
   126
            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
   127
            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
   128
        };
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   129
49374
455fce57e89e rust: don't swallow valuable error information
Raphaël Gomès <rgomes@octobus.net>
parents: 48269
diff changeset
   130
        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
   131
            .map_err(|_| PyErr::new::<ValueError, _>(
455fce57e89e rust: don't swallow valuable error information
Raphaël Gomès <rgomes@octobus.net>
parents: 48269
diff changeset
   132
                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
   133
            )?;
46432
18a261b11b20 rust: Remove hex parsing from the nodemap
Simon Sapin <simon.sapin@octobus.net>
parents: 46431
diff changeset
   134
48269
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
   135
        nt.find_bin(idx, prefix)
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
   136
            // 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
   137
            .map(|opt| opt.map(
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
   138
                |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
   139
            .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
   140
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
   141
    }
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
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   143
    /// 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
   144
    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
   145
        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
   146
            // 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
   147
            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
   148
                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
   149
        }
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
        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
   151
        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
   152
51193
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   153
        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
   154
        let mut idx = self.cindex(py).borrow_mut();
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
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   156
        // 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
   157
        let rev = Revision(rev);
51192
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   158
        idx.append(py, tup.clone_ref(py))?;
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   159
        self.index(py)
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   160
            .borrow_mut()
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   161
            .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
   162
            .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
   163
        self.get_nodetree(py)?.borrow_mut().as_mut().unwrap()
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
            .insert(&*idx, &node, 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
   165
            .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
   166
        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
   167
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   168
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
    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
   170
        // __delitem__ is both for `del idx[r]` and `del idx[r1:r2]`
51195
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51194
diff changeset
   171
        self.cindex(py).borrow().inner().del_item(py, &key)?;
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51194
diff changeset
   172
        let start = key.getattr(py, "start")?;
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51194
diff changeset
   173
        let start = UncheckedRevision(start.extract(py)?);
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51194
diff changeset
   174
        let start = self.index(py)
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51194
diff changeset
   175
            .borrow()
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51194
diff changeset
   176
            .check_revision(start)
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51194
diff changeset
   177
            .ok_or_else(|| {
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51194
diff changeset
   178
                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
   179
            })?;
f6403bcd9f96 rust-index: synchronize remove to Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51194
diff changeset
   180
        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
   181
        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
   182
        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
   183
        nt.invalidate_all();
49914
58074252db3c rust: run `cargo clippy`
Raphaël Gomès <rgomes@octobus.net>
parents: 49374
diff changeset
   184
        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
   185
        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
   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
    //
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   189
    // Reforwarded C index API
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
   190
    //
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   191
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   192
    // index_methods (tp_methods). Same ordering as in revlog.c
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   193
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   194
    /// return the gca set of the given revs
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   195
    def ancestors(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   196
        self.call_cindex(py, "ancestors", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   197
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   198
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   199
    /// return the heads of the common ancestors of the given revs
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   200
    def commonancestorsheads(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   201
        self.call_cindex(py, "commonancestorsheads", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   202
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   203
44511
cadcc8c20860 rust-nodemap: also clear Rust data in `clearcaches`
Georges Racinet <georges.racinet@octobus.net>
parents: 44510
diff changeset
   204
    /// 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
   205
    /// It is Python's responsibility to call `update_nodemap_data` again.
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   206
    def clearcaches(&self, *args, **kw) -> PyResult<PyObject> {
44511
cadcc8c20860 rust-nodemap: also clear Rust data in `clearcaches`
Georges Racinet <georges.racinet@octobus.net>
parents: 44510
diff changeset
   207
        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
   208
        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
   209
        self.nodemap_mmap(py).borrow_mut().take();
51197
4e6620b7fbbb rust-index: support cache clearing
Raphaël Gomès <rgomes@octobus.net>
parents: 51196
diff changeset
   210
        self.index(py).borrow_mut().clear_caches();
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   211
        self.call_cindex(py, "clearcaches", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   212
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   213
47034
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   214
    /// return the raw binary string representing a revision
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   215
    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
   216
        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
   217
        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
   218
        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
   219
            |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
   220
            .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
   221
        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
   222
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
   223
        let c_res = self.call_cindex(py, "entry_binary", args, kw)?;
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
   224
        assert_py_eq(py, "entry_binary", &rust_res, &c_res)?;
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
   225
        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
   226
    }
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   227
47037
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47034
diff changeset
   228
    /// return a binary packed version of the header
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47034
diff changeset
   229
    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
   230
        let rindex = self.index(py).borrow();
51cc12158f97 rust-index: add `pack_header` support
Raphaël Gomès <rgomes@octobus.net>
parents: 51197
diff changeset
   231
        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
   232
        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
   233
16d477bb0078 rust-index: return variables systematic naming convention
Georges Racinet <georges.racinet@octobus.net>
parents: 51201
diff changeset
   234
        let c_res = self.call_cindex(py, "pack_header", args, kw)?;
16d477bb0078 rust-index: return variables systematic naming convention
Georges Racinet <georges.racinet@octobus.net>
parents: 51201
diff changeset
   235
        assert_py_eq(py, "pack_header", &rust_res, &c_res)?;
16d477bb0078 rust-index: return variables systematic naming convention
Georges Racinet <georges.racinet@octobus.net>
parents: 51201
diff changeset
   236
        Ok(rust_res)
47037
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47034
diff changeset
   237
    }
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47034
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
    /// compute phases
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   240
    def computephasesmapsets(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   241
        self.call_cindex(py, "computephasesmapsets", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   242
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   243
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   244
    /// reachableroots
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   245
    def reachableroots2(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   246
        self.call_cindex(py, "reachableroots2", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   247
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   248
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   249
    /// get head revisions
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   250
    def headrevs(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   251
        self.call_cindex(py, "headrevs", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   252
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   253
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   254
    /// get filtered head revisions
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   255
    def headrevsfiltered(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   256
        self.call_cindex(py, "headrevsfiltered", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   257
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   258
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   259
    /// True if the object is a snapshot
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   260
    def issnapshot(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   261
        self.call_cindex(py, "issnapshot", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   262
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   263
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   264
    /// Gather snapshot data in a cache dict
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   265
    def findsnapshots(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   266
        self.call_cindex(py, "findsnapshots", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   267
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   268
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   269
    /// determine revisions with deltas to reconstruct fulltext
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   270
    def deltachain(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   271
        self.call_cindex(py, "deltachain", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   272
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   273
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   274
    /// slice planned chunk read to reach a density threshold
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   275
    def slicechunktodensity(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   276
        self.call_cindex(py, "slicechunktodensity", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   277
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   278
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   279
    /// stats for the index
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   280
    def stats(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   281
        self.call_cindex(py, "stats", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   282
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   283
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   284
    // 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
   285
    //
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   286
    // 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
   287
    // 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
   288
    // and index_getitem.
51205
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   289
    // 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
   290
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   291
    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
   292
        self.len(py)
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   293
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   294
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   295
    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
   296
        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
   297
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   298
        // this conversion seems needless, but that's actually because
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   299
        // `index_getitem` does not handle conversion from PyLong,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   300
        // which expressions such as [e for e in index] internally use.
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   301
        // Note that we don't seem to have a direct way to call
44511
cadcc8c20860 rust-nodemap: also clear Rust data in `clearcaches`
Georges Racinet <georges.racinet@octobus.net>
parents: 44510
diff changeset
   302
        // PySequence_GetItem (does the job), which would possibly be better
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   303
        // for performance
51205
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   304
        // gracinet 2023: the above comment can be removed when we use
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   305
        // the pure Rust impl only. Note also that `key` can be a binary
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   306
        // node id.
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   307
        let c_key = match key.extract::<BaseRevision>(py) {
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   308
            Ok(rev) => rev.to_py_object(py).into_object(),
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   309
            Err(_) => key,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   310
        };
51205
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   311
        let c_res = self.cindex(py).borrow().inner().get_item(py, c_key)?;
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   312
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   313
        assert_py_eq(py, "__getitem__", &rust_res, &c_res)?;
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   314
        Ok(rust_res)
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   315
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   316
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   317
    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
   318
        // 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
   319
        // 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
   320
        // defined in revlog.c
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   321
        let cindex = self.cindex(py).borrow();
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49914
diff changeset
   322
        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
   323
            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
   324
                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
   325
            }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   326
            Err(_) => {
51207
b67cd0d0e976 rust-index: add checks that `__contains__` is synchronized
Raphaël Gomès <rgomes@octobus.net>
parents: 51206
diff changeset
   327
                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
   328
                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
   329
b67cd0d0e976 rust-index: add checks that `__contains__` is synchronized
Raphaël Gomès <rgomes@octobus.net>
parents: 51206
diff changeset
   330
                let c_res = cindex.inner().call_method(
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   331
                    py,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   332
                    "has_node",
51207
b67cd0d0e976 rust-index: add checks that `__contains__` is synchronized
Raphaël Gomès <rgomes@octobus.net>
parents: 51206
diff changeset
   333
                    PyTuple::new(py, &[item.clone_ref(py)]),
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   334
                    None)?
51207
b67cd0d0e976 rust-index: add checks that `__contains__` is synchronized
Raphaël Gomès <rgomes@octobus.net>
parents: 51206
diff changeset
   335
                .extract(py)?;
b67cd0d0e976 rust-index: add checks that `__contains__` is synchronized
Raphaël Gomès <rgomes@octobus.net>
parents: 51206
diff changeset
   336
b67cd0d0e976 rust-index: add checks that `__contains__` is synchronized
Raphaël Gomès <rgomes@octobus.net>
parents: 51206
diff changeset
   337
                assert_eq!(rust_res, c_res);
b67cd0d0e976 rust-index: add checks that `__contains__` is synchronized
Raphaël Gomès <rgomes@octobus.net>
parents: 51206
diff changeset
   338
                Ok(rust_res)
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   339
            }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   340
        }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   341
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   342
44508
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   343
    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
   344
        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
   345
    }
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   346
44509
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   347
    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
   348
        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
   349
    }
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   350
    def update_nodemap_data(
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   351
        &self,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   352
        docket: PyObject,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   353
        nm_data: PyObject
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   354
    ) -> PyResult<PyObject> {
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   355
        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
   356
    }
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   357
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
   358
    @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
   359
    def entry_size(&self) -> PyResult<PyInt> {
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
   360
        self.cindex(py).borrow().inner().getattr(py, "entry_size")?.extract::<PyInt>(py)
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
   361
    }
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   362
47268
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47037
diff changeset
   363
    @property
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47037
diff changeset
   364
    def rust_ext_compat(&self) -> PyResult<PyInt> {
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47037
diff changeset
   365
        self.cindex(py).borrow().inner().getattr(py, "rust_ext_compat")?.extract::<PyInt>(py)
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47037
diff changeset
   366
    }
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47037
diff changeset
   367
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   368
});
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   369
51187
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   370
/// 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
   371
/// 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
   372
/// 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
   373
/// 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
   374
///
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   375
/// # Safety
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   376
///
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   377
/// 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
   378
/// 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
   379
#[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
   380
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
   381
    py: Python,
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   382
    data: PyObject,
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   383
) -> PyResult<(
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   384
    PyBuffer,
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   385
    Box<dyn std::ops::Deref<Target = [u8]> + Send + 'static>,
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   386
)> {
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   387
    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
   388
    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
   389
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   390
    // 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
   391
    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
   392
    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
   393
        && 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
   394
        && 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
   395
    {
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   396
        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
   397
    } else {
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   398
        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
   399
            py,
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   400
            "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
   401
                .to_string(),
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   402
        ));
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   403
    };
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   404
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   405
    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
   406
}
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   407
51192
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   408
fn py_tuple_to_revision_data_params(
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   409
    py: Python,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   410
    tuple: PyTuple,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   411
) -> PyResult<RevisionDataParams> {
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   412
    if tuple.len(py) < 8 {
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   413
        // 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
   414
        return Err(PyErr::new::<IndexError, _>(
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   415
            py,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   416
            "tuple index out of range",
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   417
        ));
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   418
    }
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   419
    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
   420
    let node_id = tuple
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   421
        .get_item(py, 7)
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   422
        .extract::<PyBytes>(py)?
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   423
        .data(py)
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   424
        .try_into()
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   425
        .unwrap();
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   426
    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
   427
    let data_offset = offset_or_flags >> 16;
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   428
    Ok(RevisionDataParams {
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   429
        flags,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   430
        data_offset,
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   431
        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
   432
        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
   433
        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
   434
        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
   435
        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
   436
        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
   437
        node_id,
51205
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   438
        ..Default::default()
51192
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   439
    })
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   440
}
51205
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   441
fn revision_data_params_to_py_tuple(
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   442
    py: Python,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   443
    params: RevisionDataParams,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   444
) -> PyTuple {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   445
    PyTuple::new(
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   446
        py,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   447
        &[
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   448
            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
   449
            params
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   450
                .data_compressed_length
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   451
                .into_py_object(py)
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   452
                .into_object(),
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   453
            params
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   454
                .data_uncompressed_length
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   455
                .into_py_object(py)
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   456
                .into_object(),
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   457
            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
   458
            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
   459
            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
   460
            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
   461
            PyBytes::new(py, &params.node_id)
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   462
                .into_py_object(py)
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   463
                .into_object(),
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   464
            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
   465
            params
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   466
                ._sidedata_compressed_length
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   467
                .into_py_object(py)
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   468
                .into_object(),
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   469
            params
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   470
                .data_compression_mode
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   471
                .into_py_object(py)
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   472
                .into_object(),
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   473
            params
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   474
                ._sidedata_compression_mode
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   475
                .into_py_object(py)
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   476
                .into_object(),
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   477
            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
   478
        ],
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   479
    )
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   480
}
51192
65c9032e2e5a rust-index: synchronize append method
Raphaël Gomès <rgomes@octobus.net>
parents: 51191
diff changeset
   481
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   482
impl MixedIndex {
51190
6ec8387eb0be rust-index: pass data down to the Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51187
diff changeset
   483
    fn new(
6ec8387eb0be rust-index: pass data down to the Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51187
diff changeset
   484
        py: Python,
6ec8387eb0be rust-index: pass data down to the Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51187
diff changeset
   485
        cindex: PyObject,
6ec8387eb0be rust-index: pass data down to the Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51187
diff changeset
   486
        data: PyObject,
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
   487
        header: u32,
51190
6ec8387eb0be rust-index: pass data down to the Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51187
diff changeset
   488
    ) -> PyResult<MixedIndex> {
6ec8387eb0be rust-index: pass data down to the Rust index
Raphaël Gomès <rgomes@octobus.net>
parents: 51187
diff changeset
   489
        // 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
   490
        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
   491
44503
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
   492
        Self::create_instance(
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
   493
            py,
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
   494
            RefCell::new(cindex::Index::new(py, cindex)?),
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
   495
            RefCell::new(
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51190
diff changeset
   496
                hg::index::Index::new(
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51190
diff changeset
   497
                    bytes,
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51190
diff changeset
   498
                    IndexHeader::parse(&header.to_be_bytes())
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51190
diff changeset
   499
                        .expect("default header is broken")
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51190
diff changeset
   500
                        .unwrap(),
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51190
diff changeset
   501
                )
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51190
diff changeset
   502
                .unwrap(),
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Raphaël Gomès <rgomes@octobus.net>
parents: 51190
diff changeset
   503
            ),
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
   504
            RefCell::new(None),
44509
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   505
            RefCell::new(None),
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   506
            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
   507
            RefCell::new(Some(buf)),
44503
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
   508
        )
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
   509
    }
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
   510
51193
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   511
    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
   512
        let rust_index_len = self.index(py).borrow().len();
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   513
        let cindex_len = self.cindex(py).borrow().inner().len(py)?;
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   514
        assert_eq!(rust_index_len, cindex_len);
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   515
        Ok(cindex_len)
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   516
    }
e79b0a4be3a7 rust-index: check equality between rust and cindex for `__len__`
Raphaël Gomès <rgomes@octobus.net>
parents: 51192
diff changeset
   517
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
   518
    /// 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
   519
    /// 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
   520
    /// 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
   521
    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
   522
        &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
   523
        py: Python,
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   524
        nt: &mut NodeTree,
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   525
    ) -> PyResult<PyObject> {
51206
952e3cd7568f rust-index: using the Rust index in nodemap updating methods
Georges Racinet <georges.racinet@octobus.net>
parents: 51205
diff changeset
   526
        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
   527
        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
   528
            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
   529
            // 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
   530
            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
   531
                .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
   532
        }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   533
        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
   534
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   535
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   536
    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
   537
        &'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
   538
        py: Python<'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
   539
    ) -> PyResult<&'a RefCell<Option<NodeTree>>> {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   540
        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
   541
            let readonly = Box::<Vec<_>>::default();
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
   542
            let mut nt = NodeTree::load_bytes(readonly, 0);
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   543
            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
   544
            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
   545
        }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   546
        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
   547
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   548
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   549
    /// forward a method call to the underlying C index
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   550
    fn call_cindex(
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   551
        &self,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   552
        py: Python,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   553
        name: &str,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   554
        args: &PyTuple,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   555
        kwargs: Option<&PyDict>,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   556
    ) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   557
        self.cindex(py)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   558
            .borrow()
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   559
            .inner()
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   560
            .call_method(py, name, args, kwargs)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   561
    }
44010
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43961
diff changeset
   562
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43961
diff changeset
   563
    pub fn clone_cindex(&self, py: Python) -> cindex::Index {
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43961
diff changeset
   564
        self.cindex(py).borrow().clone_ref(py)
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43961
diff changeset
   565
    }
44508
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   566
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   567
    /// 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
   568
    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
   569
        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
   570
        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
   571
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   572
        // 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
   573
        // scratch
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   574
        let bytes = if readonly.len() > 0 {
51120
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Raphaël Gomès <rgomes@octobus.net>
parents: 50979
diff changeset
   575
            let mut nt = NodeTree::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
   576
            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
   577
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   578
            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
   579
            assert_eq!(readonly.len(), 0);
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   580
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   581
            bytes
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   582
        } else {
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   583
            bytes
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   584
        };
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   585
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   586
        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
   587
        Ok(bytes)
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   588
    }
44509
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   589
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   590
    /// 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
   591
    /// (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
   592
    fn inner_nodemap_data_incremental(
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   593
        &self,
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   594
        py: Python,
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   595
    ) -> PyResult<PyObject> {
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   596
        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
   597
        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
   598
            Some(d) => d,
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   599
            None => return Ok(py.None()),
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   600
        };
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   601
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   602
        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
   603
        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
   604
        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
   605
        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
   606
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   607
        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
   608
            .to_py_object(py)
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   609
            .into_object())
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   610
    }
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   611
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   612
    /// 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
   613
    /// 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
   614
    fn inner_update_nodemap_data(
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   615
        &self,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   616
        py: Python,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   617
        docket: PyObject,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   618
        nm_data: PyObject,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   619
    ) -> 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
   620
        // 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
   621
        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
   622
        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
   623
        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
   624
51187
8c4e8d06432e rust-mixed-index: move the mmap keepalive into a function
Raphaël Gomès <rgomes@octobus.net>
parents: 51186
diff changeset
   625
        let mut nt = NodeTree::load_bytes(bytes, len);
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   626
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   627
        let data_tip = docket
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   628
            .getattr(py, "tip_rev")?
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   629
            .extract::<BaseRevision>(py)?
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   630
            .into();
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   631
        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
   632
        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
   633
        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
   634
            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
   635
        })?;
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   636
        let current_tip = idx.len();
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   637
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   638
        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
   639
            let rev = Revision(r);
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   640
            // 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
   641
            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
   642
                .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
   643
        }
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   644
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   645
        *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
   646
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   647
        Ok(py.None())
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   648
    }
51205
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   649
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   650
    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
   651
        let idx = self.index(py).borrow();
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   652
        Ok(match key.extract::<BaseRevision>(py) {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   653
            Ok(key_as_int) => {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   654
                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
   655
                    RevisionDataParams::default()
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   656
                } else {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   657
                    let rev = UncheckedRevision(key_as_int);
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   658
                    match idx.entry_as_params(rev) {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   659
                        Some(e) => e,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   660
                        None => {
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   661
                            return Err(PyErr::new::<IndexError, _>(
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   662
                                py,
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   663
                                "revlog index out of range",
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   664
                            ));
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   665
                        }
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   666
                    }
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   667
                };
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   668
                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
   669
                    .into_object()
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   670
            }
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   671
            _ => 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
   672
                || py.None(),
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   673
                |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
   674
            ),
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   675
        })
002b49905aac rust-index: implementation of __getitem__
Raphaël Gomès <rgomes@octobus.net>
parents: 51204
diff changeset
   676
    }
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   677
}
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   678
44506
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   679
fn revlog_error(py: Python) -> PyErr {
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   680
    match py
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   681
        .import("mercurial.error")
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   682
        .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
   683
    {
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   684
        Err(e) => e,
47305
33e7508b0ae9 hg-cpython: fix new occuring TypeError
Raphaël Gomès <rgomes@octobus.net>
parents: 47268
diff changeset
   685
        Ok(cls) => PyErr::from_instance(
33e7508b0ae9 hg-cpython: fix new occuring TypeError
Raphaël Gomès <rgomes@octobus.net>
parents: 47268
diff changeset
   686
            py,
33e7508b0ae9 hg-cpython: fix new occuring TypeError
Raphaël Gomès <rgomes@octobus.net>
parents: 47268
diff changeset
   687
            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
   688
        ),
44506
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   689
    }
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   690
}
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   691
51199
44fbb7dfb563 rust-index: renamed nodemap error function for rev not in index
Georges Racinet <georges.racinet@octobus.net>
parents: 51198
diff changeset
   692
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
   693
    PyErr::new::<ValueError, _>(
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   694
        py,
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   695
        format!(
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   696
            "Inconsistency: Revision {} found in nodemap \
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   697
             is not in revlog index",
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   698
            rev
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   699
        ),
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   700
    )
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   701
}
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   702
51200
bc4d83047c6c rust-index: helper for revision not in index not involving nodemap
Georges Racinet <georges.racinet@octobus.net>
parents: 51199
diff changeset
   703
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
   704
    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
   705
        py,
bc4d83047c6c rust-index: helper for revision not in index not involving nodemap
Georges Racinet <georges.racinet@octobus.net>
parents: 51199
diff changeset
   706
        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
   707
    )
bc4d83047c6c rust-index: helper for revision not in index not involving nodemap
Georges Racinet <georges.racinet@octobus.net>
parents: 51199
diff changeset
   708
}
bc4d83047c6c rust-index: helper for revision not in index not involving nodemap
Georges Racinet <georges.racinet@octobus.net>
parents: 51199
diff changeset
   709
44506
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   710
/// Standard treatment of NodeMapError
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   711
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
   712
    match err {
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   713
        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
   714
        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
   715
    }
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   716
}
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   717
51201
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   718
fn assert_py_eq(
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   719
    py: Python,
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   720
    method: &str,
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   721
    rust: &PyObject,
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   722
    c: &PyObject,
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   723
) -> PyResult<()> {
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   724
    let locals = PyDict::new(py);
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   725
    locals.set_item(py, "rust".into_py_object(py).into_object(), rust)?;
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   726
    locals.set_item(py, "c".into_py_object(py).into_object(), c)?;
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   727
    let is_eq: PyBool =
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   728
        py.eval("rust == c", None, Some(&locals))?.extract(py)?;
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   729
    assert!(
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   730
        is_eq.is_true(),
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   731
        "{} results differ. Rust: {:?} C: {:?}",
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   732
        method,
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   733
        rust,
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   734
        c
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   735
    );
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   736
    Ok(())
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   737
}
52bbb57a76ad rust-index: results comparison helper with details
Georges Racinet <georges.racinet@octobus.net>
parents: 51200
diff changeset
   738
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   739
/// 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
   740
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
   741
    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
   742
    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
   743
    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
   744
    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
   745
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   746
    m.add_class::<MixedIndex>(py)?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   747
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   748
    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
   749
    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
   750
    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
   751
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   752
    Ok(m)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   753
}