rust/hg-cpython/src/cindex.rs
author Rapha?l Gom?s <rgomes@octobus.net>
Fri, 18 Aug 2023 14:34:29 +0200
changeset 50976 4c5f6e95df84
parent 50972 3aca98a35727
child 51250 96e05f1a99bd
permissions -rw-r--r--
rust: make `Revision` a newtype This change is the one we've been building towards during this series. The aim is to make `Revision` mean more than a simple integer, holding the information that it is valid for a given revlog index. While this still allows for programmer error, since creating a revision directly and querying a different index with a "checked" revision are still possible, the friction created by the newtype will hopefully make us think twice about which type to use. Enough of the Rust ecosystem relies on the newtype pattern to be efficiently optimized away (even compiler in codegen tests?), so I'm not worried about this being a fundamental problem. [1] https://github.com/rust-lang/rust/blob/7a70647f195f6b0a0f1ebd72b1542ba91a32f43a/tests/codegen/vec-in-place.rs#L47
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
     1
// cindex.rs
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
     2
//
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
     3
// Copyright 2018 Georges Racinet <gracinet@anybox.fr>
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
     4
//
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
     7
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
     8
//! Bindings to use the Index defined by the parsers C extension
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
     9
//!
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    10
//! Ideally, we should use an Index entirely implemented in Rust,
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    11
//! but this will take some time to get there.
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    12
44504
cefd130c98be rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents: 44502
diff changeset
    13
use cpython::{
47268
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46412
diff changeset
    14
    exc::ImportError, exc::TypeError, ObjectProtocol, PyClone, PyErr,
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46412
diff changeset
    15
    PyObject, PyResult, PyTuple, Python, PythonObject,
44504
cefd130c98be rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents: 44502
diff changeset
    16
};
44502
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
    17
use hg::revlog::{Node, RevlogIndex};
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50972
diff changeset
    18
use hg::{BaseRevision, Graph, GraphError, Revision};
46412
7d0405e458a0 persistent-nodemap: Fix Rust declarations for Revlog_CAPI signatures
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
    19
use libc::{c_int, ssize_t};
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    20
48852
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48518
diff changeset
    21
const REVLOG_CABI_VERSION: c_int = 3;
44066
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44010
diff changeset
    22
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
    23
#[repr(C)]
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
    24
pub struct Revlog_CAPI {
44066
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44010
diff changeset
    25
    abi_version: c_int,
44502
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
    26
    index_length:
46412
7d0405e458a0 persistent-nodemap: Fix Rust declarations for Revlog_CAPI signatures
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
    27
        unsafe extern "C" fn(index: *mut revlog_capi::RawPyObject) -> ssize_t,
44502
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
    28
    index_node: unsafe extern "C" fn(
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
    29
        index: *mut revlog_capi::RawPyObject,
46412
7d0405e458a0 persistent-nodemap: Fix Rust declarations for Revlog_CAPI signatures
Simon Sapin <simon.sapin@octobus.net>
parents: 44973
diff changeset
    30
        rev: ssize_t,
44502
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
    31
    ) -> *const Node,
48852
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48518
diff changeset
    32
    fast_rank: unsafe extern "C" fn(
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48518
diff changeset
    33
        index: *mut revlog_capi::RawPyObject,
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48518
diff changeset
    34
        rev: ssize_t,
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48518
diff changeset
    35
    ) -> ssize_t,
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
    36
    index_parents: unsafe extern "C" fn(
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
    37
        index: *mut revlog_capi::RawPyObject,
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
    38
        rev: c_int,
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
    39
        ps: *mut [c_int; 2],
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
    40
    ) -> c_int,
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
    41
}
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
    42
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
    43
py_capsule!(
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
    44
    from mercurial.cext.parsers import revlog_CAPI
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
    45
        as revlog_capi for Revlog_CAPI);
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    46
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    47
/// A `Graph` backed up by objects and functions from revlog.c
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    48
///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    49
/// This implementation of the `Graph` trait, relies on (pointers to)
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    50
/// - the C index object (`index` member)
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    51
/// - the `index_get_parents()` function (`parents` member)
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    52
///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    53
/// # Safety
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    54
///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    55
/// The C index itself is mutable, and this Rust exposition is **not
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    56
/// protected by the GIL**, meaning that this construct isn't safe with respect
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    57
/// to Python threads.
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    58
///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    59
/// All callers of this `Index` must acquire the GIL and must not release it
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    60
/// while working.
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    61
///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    62
/// # TODO find a solution to make it GIL safe again.
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    63
///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    64
/// This is non trivial, and can wait until we have a clearer picture with
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    65
/// more Rust Mercurial constructs.
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    66
///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    67
/// One possibility would be to a `GILProtectedIndex` wrapper enclosing
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    68
/// a `Python<'p>` marker and have it be the one implementing the
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    69
/// `Graph` trait, but this would mean the `Graph` implementor would become
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    70
/// likely to change between subsequent method invocations of the `hg-core`
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    71
/// objects (a serious change of the `hg-core` API):
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    72
/// either exposing ways to mutate the `Graph`, or making it a non persistent
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    73
/// parameter in the relevant methods that need one.
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    74
///
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    75
/// Another possibility would be to introduce an abstract lock handle into
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    76
/// the core API, that would be tied to `GILGuard` / `Python<'p>`
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    77
/// in the case of the `cpython` crate bindings yet could leave room for other
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    78
/// mechanisms in other contexts.
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    79
pub struct Index {
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    80
    index: PyObject,
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
    81
    capi: &'static Revlog_CAPI,
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    82
}
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    83
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    84
impl Index {
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
    85
    pub fn new(py: Python, index: PyObject) -> PyResult<Self> {
44066
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44010
diff changeset
    86
        let capi = unsafe { revlog_capi::retrieve(py)? };
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44010
diff changeset
    87
        if capi.abi_version != REVLOG_CABI_VERSION {
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44010
diff changeset
    88
            return Err(PyErr::new::<ImportError, _>(
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44010
diff changeset
    89
                py,
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44010
diff changeset
    90
                format!(
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44010
diff changeset
    91
                    "ABI version mismatch: the C ABI revlog version {} \
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44010
diff changeset
    92
                     does not match the {} expected by Rust hg-cpython",
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44010
diff changeset
    93
                    capi.abi_version, REVLOG_CABI_VERSION
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44010
diff changeset
    94
                ),
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44010
diff changeset
    95
            ));
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 44010
diff changeset
    96
        }
47268
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46412
diff changeset
    97
        let compat: u64 = index.getattr(py, "rust_ext_compat")?.extract(py)?;
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46412
diff changeset
    98
        if compat == 0 {
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46412
diff changeset
    99
            return Err(PyErr::new::<TypeError, _>(
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46412
diff changeset
   100
                py,
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46412
diff changeset
   101
                "index object not compatible with Rust",
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46412
diff changeset
   102
            ));
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46412
diff changeset
   103
        }
44973
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44504
diff changeset
   104
        Ok(Index { index, capi })
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   105
    }
43960
ab3fd8077f5e rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents: 43959
diff changeset
   106
ab3fd8077f5e rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents: 43959
diff changeset
   107
    /// return a reference to the CPython Index object in this Struct
ab3fd8077f5e rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents: 43959
diff changeset
   108
    pub fn inner(&self) -> &PyObject {
ab3fd8077f5e rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents: 43959
diff changeset
   109
        &self.index
ab3fd8077f5e rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents: 43959
diff changeset
   110
    }
44504
cefd130c98be rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents: 44502
diff changeset
   111
cefd130c98be rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents: 44502
diff changeset
   112
    pub fn append(&mut self, py: Python, tup: PyTuple) -> PyResult<PyObject> {
cefd130c98be rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents: 44502
diff changeset
   113
        self.index.call_method(
cefd130c98be rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents: 44502
diff changeset
   114
            py,
cefd130c98be rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents: 44502
diff changeset
   115
            "append",
cefd130c98be rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents: 44502
diff changeset
   116
            PyTuple::new(py, &[tup.into_object()]),
cefd130c98be rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents: 44502
diff changeset
   117
            None,
cefd130c98be rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents: 44502
diff changeset
   118
        )
cefd130c98be rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents: 44502
diff changeset
   119
    }
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   120
}
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   121
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41052
diff changeset
   122
impl Clone for Index {
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41052
diff changeset
   123
    fn clone(&self) -> Self {
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41052
diff changeset
   124
        let guard = Python::acquire_gil();
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41052
diff changeset
   125
        Index {
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41052
diff changeset
   126
            index: self.index.clone_ref(guard.python()),
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
   127
            capi: self.capi,
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41052
diff changeset
   128
        }
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41052
diff changeset
   129
    }
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41052
diff changeset
   130
}
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 41052
diff changeset
   131
44010
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43960
diff changeset
   132
impl PyClone for Index {
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43960
diff changeset
   133
    fn clone_ref(&self, py: Python) -> Self {
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43960
diff changeset
   134
        Index {
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43960
diff changeset
   135
            index: self.index.clone_ref(py),
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43960
diff changeset
   136
            capi: self.capi,
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43960
diff changeset
   137
        }
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43960
diff changeset
   138
    }
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43960
diff changeset
   139
}
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43960
diff changeset
   140
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   141
impl Graph for Index {
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   142
    /// wrap a call to the C extern parents function
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   143
    fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> {
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   144
        let mut res: [c_int; 2] = [0; 2];
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   145
        let code = unsafe {
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43213
diff changeset
   146
            (self.capi.index_parents)(
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   147
                self.index.as_ptr(),
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50972
diff changeset
   148
                rev.0 as c_int,
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   149
                &mut res as *mut [c_int; 2],
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   150
            )
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   151
        };
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   152
        match code {
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50972
diff changeset
   153
            0 => Ok([Revision(res[0]), Revision(res[1])]),
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   154
            _ => Err(GraphError::ParentOutOfRange(rev)),
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   155
        }
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   156
    }
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
   157
}
44502
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   158
48518
8e8737a1fa7d hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents: 47268
diff changeset
   159
impl vcsgraph::graph::Graph for Index {
8e8737a1fa7d hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents: 47268
diff changeset
   160
    fn parents(
8e8737a1fa7d hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents: 47268
diff changeset
   161
        &self,
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50972
diff changeset
   162
        rev: BaseRevision,
48518
8e8737a1fa7d hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents: 47268
diff changeset
   163
    ) -> Result<vcsgraph::graph::Parents, vcsgraph::graph::GraphReadError>
8e8737a1fa7d hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents: 47268
diff changeset
   164
    {
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50972
diff changeset
   165
        // FIXME This trait should be reworked to decide between Revision
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50972
diff changeset
   166
        // and UncheckedRevision, get better errors names, etc.
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50972
diff changeset
   167
        match Graph::parents(self, Revision(rev)) {
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50972
diff changeset
   168
            Ok(parents) => {
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50972
diff changeset
   169
                Ok(vcsgraph::graph::Parents([parents[0].0, parents[1].0]))
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50972
diff changeset
   170
            }
48518
8e8737a1fa7d hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents: 47268
diff changeset
   171
            Err(GraphError::ParentOutOfRange(rev)) => {
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50972
diff changeset
   172
                Err(vcsgraph::graph::GraphReadError::KeyedInvalidKey(rev.0))
48518
8e8737a1fa7d hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents: 47268
diff changeset
   173
            }
8e8737a1fa7d hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents: 47268
diff changeset
   174
        }
8e8737a1fa7d hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents: 47268
diff changeset
   175
    }
8e8737a1fa7d hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents: 47268
diff changeset
   176
}
8e8737a1fa7d hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents: 47268
diff changeset
   177
48853
4346be456875 rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents: 48852
diff changeset
   178
impl vcsgraph::graph::RankedGraph for Index {
4346be456875 rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents: 48852
diff changeset
   179
    fn rank(
4346be456875 rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents: 48852
diff changeset
   180
        &self,
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50972
diff changeset
   181
        rev: BaseRevision,
48853
4346be456875 rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents: 48852
diff changeset
   182
    ) -> Result<vcsgraph::graph::Rank, vcsgraph::graph::GraphReadError> {
4346be456875 rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents: 48852
diff changeset
   183
        match unsafe {
4346be456875 rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents: 48852
diff changeset
   184
            (self.capi.fast_rank)(self.index.as_ptr(), rev as ssize_t)
4346be456875 rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents: 48852
diff changeset
   185
        } {
4346be456875 rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents: 48852
diff changeset
   186
            -1 => Err(vcsgraph::graph::GraphReadError::InconsistentGraphData),
4346be456875 rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents: 48852
diff changeset
   187
            rank => Ok(rank as usize),
4346be456875 rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents: 48852
diff changeset
   188
        }
4346be456875 rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents: 48852
diff changeset
   189
    }
4346be456875 rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents: 48852
diff changeset
   190
}
4346be456875 rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents: 48852
diff changeset
   191
44502
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   192
impl RevlogIndex for Index {
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   193
    /// Note C return type is Py_ssize_t (hence signed), but we shall
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   194
    /// force it to unsigned, because it's a length
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   195
    fn len(&self) -> usize {
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   196
        unsafe { (self.capi.index_length)(self.index.as_ptr()) as usize }
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   197
    }
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   198
44973
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44504
diff changeset
   199
    fn node(&self, rev: Revision) -> Option<&Node> {
44502
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   200
        let raw = unsafe {
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50972
diff changeset
   201
            (self.capi.index_node)(self.index.as_ptr(), rev.0 as ssize_t)
44502
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   202
        };
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   203
        if raw.is_null() {
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   204
            None
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   205
        } else {
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   206
            // TODO it would be much better for the C layer to give us
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   207
            // a length, since the hash length will change in the near
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   208
            // future, but that's probably out of scope for the nodemap
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   209
            // patch series.
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   210
            //
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   211
            // The root of that unsafety relies in the signature of
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   212
            // `capi.index_node()` itself: returning a `Node` pointer
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   213
            // whereas it's a `char *` in the C counterpart.
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   214
            Some(unsafe { &*raw })
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   215
        }
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   216
    }
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44066
diff changeset
   217
}